Search code examples
pythonvirtualenvgunicorn

How to run Gunicorn inside virtualenv?


Background

I'm currently configuring a Nginx + Gunicorn + Django + virtualenv setup. I have a prod_settings which will be used for production, and set DJANGO_SETTINGS_MODULE env variables to it by adding export DJANGO_SETTINGS_MODULE=project.prod_settings to project/venv/bin/activate. This works perfectly if I first run source project/venv/bin/activate.

Now I followed Instructions from DigitalOcean to use systemd to monitor Gunicorn.

Inside gunicorn.service file, I have ExecStart=/path/to/project/venv/bin/gunicorn.

Problem

  1. If .../venv/bin/gunicorn runs inside virtualenv, will it activate virtualenv if I call this command from a system environment?

  2. Also, I'm absolutely sure that calling .../venv/bin/gunicorn from system env won't trigger source /project/venv/activate as the env variables are not defined.

  3. Since .../venv/bin/gunicorn can be run from the system env, I wonder how it finds the lib of the virtualenv, instead of lib of the system?

This is how ../venv/bin/gunicorn looks

#!/home/hao/Eng-Memo/venv/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from gunicorn.app.wsgiapp import run
if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
    sys.exit(run())

Some reference resources can be extremely helpful!


Solution

  • I think I finally figured this out. According to Python Official docs:

    You don’t specifically need to activate a virtual environment, as you can just specify the full path to that environment’s Python interpreter when invoking Python. Furthermore, all scripts installed in the environment should be runnable without activating it.

    In order to achieve this, scripts installed into virtual environments have a “shebang” line which points to the environment’s Python interpreter, i.e. #!//bin/python. This means that the script will run with that interpreter regardless of the value of PATH. On Windows, “shebang” line processing is supported if you have the Python Launcher for Windows installed. Thus, double-clicking an installed script in a Windows Explorer window should run it with the correct interpreter without the environment needing to be activated or on the PATH.

    So the first line of ../venv/bin/gunicorn, which looks like a comment actually plays a huge role. It specifies the Python interpreter to be used is the one of virtualenv. Hence, sys.path will add the site-packages folder inside lib of the virtualenv.