Running Python script via systemd fails to load module

13,106

Solution 1

systemd runs as root. The modules installed via pip are installed for a user rather than for the system and so installing the modules without root privileges made the modules unaccessible for root.

To solve this I ran sudo -H pip install zmq and sudo -H pip3 install zmq to install the packages for both Python 2.7 and Python 3+ for root. This allowed systemd to access the modules once it attempts to execute the Python script.

Solution 2

Add this property to [Service] section to make sure systemd run as the specified user.

User=pi

Refer to the solution of AndyD.

Solution 3

The most likely explanation is that you have some environment variables set (e.g. an extension of your PYTHONPATH?) which is not set when the script is being run by systemd.

You could try using the Environment parameter (see [0]) so set PYTHONPATH (and whatever else might influence this) to whatever it is in your console session.

[0] http://0pointer.de/public/systemd-man/systemd.exec.html#Environment=

Solution 4

In my case I set "EnvironmentFile=" to the user .bash_profile. The issue was that in .bash_profile I had something like:

export PYTHONPATH=....
export PATH=....

This did not worked with systemd and I had to changed it to:

PYTHONPATH=....
PATH=....
export PYTHONPATH PATH
Share:
13,106
Shiri
Author by

Shiri

Updated on June 05, 2022

Comments

  • Shiri
    Shiri almost 2 years

    I have a Python script that uses zmq and I've installed this library via pip install zmq and I can run the program fine if called manually via the command line. However as soon as I attempt to have a systemd unit call the script, running systemctl status myservice.service shows ImportError: No module named zmq.

    My service file looks like this:

    [Unit]
    Description=Does Something
    
    [Service]
    Type=simple
    ExecStart=/bin/sh /var/lib/project/runpythonscript.sh
    Restart=always
    
    [Install]
    Alias=myservice.service
    

    Where runpythonscript.sh is a very simple shell script that runs my python script as root. Running this shell script manually from the command line runs my python program completely fine but having the service call it causes it to not locate the zmq module.

    Any help is appreciated.

  • dtgee
    dtgee almost 8 years
    Thank you! This answer has finally helped me get my project to work after hours of searching for answers that didn't.
  • L.P. Whigley
    L.P. Whigley over 5 years
    This is by far the quickest and best solution I have found for this issue!
  • Phill Healey
    Phill Healey about 4 years
    This is the most efficient and safe way to do it.
  • ThisGuyCantEven
    ThisGuyCantEven almost 4 years
    Or use User=<pip_user> in your unitfile to have your python run as that user. Your python shouldn't run as root unless it needs to.