Libraries Found when Running from the Command Line but Not When Running From Supervisor (Ubuntu 18.04)

You might want to do a quick sanity check to see if your supervisor is not just completely stopped or completely broken. Do this like so:

sudo systemctl status supervisor

and you will see some output like:

? supervisor.service - Supervisor process control system for UNIX
Loaded: loaded (/lib/systemd/system/supervisor.service; enabled; vendor preset: enabled)
Active: activating (auto-restart) (Result: exit-code) since Mon 2019-08-19 21:28:18 CDT; 10s ago
Docs: http://supervisord.org
Process: 15183 ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown (code=exited, status=0/SUCCESS)
Process: 15920 ExecStart=/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf (code=exited, status=2)
Main PID: 15920 (code=exited, status=2)

See how the bottom line says exited? Check that out. That can happen if you have something screwy in your supervisor.conf file.

You can find your supervisor config file under /etc/supervisor if you installed with apt-get. You can check that file to see where your logs are. You probably want to install this way as opposed to pip so that supervisor will start on system boot.

My logs are under /var/log/supervisor.

Running from the command line I can run my script just fine but when I check the supervisor logs I see:

ModuleNotFoundError: No module named 'cv2'

In your supervisor.conf file where you have your program defined, there is a property called environment. I can usually add my PATH to that environment and get most things working just by doing that. There is usually a few stragglers though that I have to find the path to and add in manually.

; supervisor config file[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod=0700 ; sockef file mode (default 0700)
;[inet_http_server]
;port=127.0.0.1:9001
;username=myusername
;password=mypassword
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
loglevel=blather
; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
[program:my_program_name]
command=/bin/bash -c "python3 /path/to/program.py"
process_name=%(program_name)s
numprocs=1
autostart=true
startsecs=3
stdout_events_enabled=true
environment=PATH=/home/topaz/.local/bin:/usr/local/cuda-9.0/bin/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/lib/python3.6:/usr/lib/python3.6/lib-dynload:/home/topaz/.local/lib/python3.6/site-packages:/usr/local/lib/python3.6/dist-packages:/usr/lib/python3/dist-packages
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = /etc/supervisor/conf.d/*.conf

I pretty much do

echo $PATH

and then paste the result of that in the supervisord.conf file. (You have to add in PATH= part yourself too)

so where is the path to cv2?

Do this. Open a console session by typing python3 and pressing enter.

$ python3

You’ll see that your prompts now start with >>>.

Type in these two lines to see the path to the cv2 module. Replace cv2 with whatever module it is that you in particular are looking for.

>>> import cv2
>>> print(cv2.__file__)

I got the result:

/home/username/.local/lib/python3.6/site-packages/cv2/cv2.cpython-36m-x86_64-linux-gnu.so

Take the .so file (or whatever file in your case) off the end and add that to the path in your supervisor environment variable. ie. just this part:

/home/username/.local/lib/python3.6/site-packages/cv2/

Add this:

environment=PATH=/my/path/stuff, PYTHONPATH=/home/username/.local/lib/python3.6/site-packages/cv2/

You’re basically adding the path to cv2 to an environment variable for supervisor called PYTHONPATH. (scroll horizontally to the end if you can’t see it)

Do these two commands to restart your supervisor. If you are in charge of a bunch of important stuff, you might want to make sure that your long running processes are not in the middle of doing something first.

sudo service supervisor stop
sudo service supervisor start

Now when I do this:

$ sudo systemctl status supervisor
? supervisor.service - Supervisor process control system for UNIX
Loaded: loaded (/lib/systemd/system/supervisor.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2019-08-19 21:39:50 CDT; 3min 57s ago
Docs: http://supervisord.org
Process: 16350 ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown (code=exited, status=0/SUCCESS)
Main PID: 16390 (supervisord)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/supervisor.service
+-16390 /usr/bin/python /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
supervisord[16390]: File "/home/username/path/to/program.py", line 1, in <module>
supervisord[16390]: from easydict import EasyDict as edict
supervisord[16390]: ModuleNotFoundError: No module named 'easydict'

I can see that I have fixed the opencv error because it has moved on to the next module it can’t find. Repeat this for every module that supervisor can’t find and you should be good.