When migrating Python applications from development (Mac OSX) to production (Ubuntu), a common pain point emerges: Supervisord doesn't automatically activate virtual environments like we expect. The symptoms typically include:
ImportError: No module named 'some_package'
ModuleNotFoundError: Python can't find dependencies
Supervisord executes commands in a clean environment by default, which means:
- Environment variables from .bashrc/.profile aren't sourced
- The PATH isn't inherited from your user session
- Virtualenv activation scripts aren't automatically run
1. Direct Virtualenv Python Path
Specify the full path to your virtualenv's Python executable:
[program:python-app]
command = /home/user/Sites/my-site/venv/bin/python app.py
directory = /home/user/Sites/my-site
user = user
2. Environment Variables Approach
Manually set the virtualenv's PATH and PYTHONPATH:
[program:python-app]
command = python app.py
directory = /home/user/Sites/my-site
environment=
PATH="/home/user/Sites/my-site/venv/bin:%(ENV_PATH)s",
VIRTUAL_ENV="/home/user/Sites/my-site/venv",
PYTHONPATH="/home/user/Sites/my-site"
3. Source Activation Script (Advanced)
For complex environments requiring full activation:
[program:python-app]
command = bash -c 'source /home/user/Sites/my-site/venv/bin/activate && exec python app.py'
directory = /home/user/Sites/my-site
Here's a complete optimized configuration:
[program:python-app]
command = /home/user/Sites/my-site/venv/bin/python app.py
directory = /home/user/Sites/my-site
user = www-data
autostart = true
autorestart = true
startsecs = 5
stopwaitsecs = 30
stdout_logfile = /var/log/supervisor/python-app.out.log
stderr_logfile = /var/log/supervisor/python-app.err.log
environment=
DJANGO_SETTINGS_MODULE="app.settings.production",
PYTHONDONTWRITEBYTECODE="1"
To verify your environment is properly set up:
# Check which Python is being used
supervisorctl tail python-app
# Test environment variables
[program:python-debug]
command = /home/user/Sites/my-site/venv/bin/python -c "import os; print(os.environ)"
When deploying Python applications on Ubuntu with Supervisor, a common issue arises: Supervisor doesn't automatically activate the virtual environment, leading to import errors and dependency issues. This is particularly frustrating when the same configuration works perfectly on Mac OSX.
The key difference lies in how Supervisor executes commands. Unlike running scripts manually where you'd typically source venv/bin/activate
, Supervisor needs explicit instructions to use the virtual environment's Python interpreter and site-packages.
Here's how to modify your supervisor.conf to properly use virtualenv:
[program:python-app]
command=/home/user/Sites/my-site/venv/bin/python /home/user/Sites/my-site/app.py
directory=/home/user/Sites/my-site
user=user
autostart=true
autorestart=true
stderr_logfile=/var/log/python-app.err.log
stdout_logfile=/var/log/python-app.out.log
environment=
PYTHONPATH="/home/user/Sites/my-site",
VIRTUAL_ENV="/home/user/Sites/my-site/venv",
PATH="/home/user/Sites/my-site/venv/bin:%(ENV_PATH)s"
- Absolute paths: Always use full paths to both the Python interpreter and your script
- Environment variables: Explicitly set PYTHONPATH and VIRTUAL_ENV
- PATH modification: Prepend the virtualenv's bin directory to ensure correct package resolution
After updating your configuration, test it with:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start python-app
Check the logs to confirm everything is working:
tail -f /var/log/python-app.out.log
Some prefer to explicitly activate the virtual environment. Here's how:
[program:python-app]
command=bash -c 'source /home/user/Sites/my-site/venv/bin/activate && python app.py'
...
If you still encounter problems:
- Verify file permissions on your virtualenv
- Check that Supervisor is running as the correct user
- Ensure all dependencies are installed in the virtualenv
- Confirm the Python version in virtualenv matches your requirements
- Use absolute paths for all file references
- Maintain separate virtualenvs for different applications
- Implement proper logging rotation
- Consider using environment files for sensitive variables