'How to deploy a django/gunicorn application as a systemd service?

Context

For the last few years, I have been only using docker to containerize and distribute django applications. For the first time, I am asked to set things so it could be deployed the old way. I am looking for a way to nearly achieve the levels of encapsulation and automation I am used to while avoiding any pitfalls

Current heuristic

So, the application (my_app):

  • is build as a .whl
  • comes with gunicorn
  • is published on a private Nexus and
  • can be installed on any of the client's server with a simple pip install

(it relies on Apache as reverse proxy / static files server and Postgresql but this is irrelevant for this discussion)

To make sure that the app will remain available, I thought about running it as a service managed by systemd. Based on this article, here is what /etc/systemd/system/my_app.service could look like

[Unit]
Description=My app service
After=network.target
StartLimitIntervalSec=0[Service]
Type=simple
Restart=always
RestartSec=1
User=centos
ExecStart=gunicorn my_app.wsgi:application --bind 8000

[Install]
WantedBy=multi-user.target

and, from what I understand, I could provide this service with environment variables to be read by os.environ.get() somewhere in /etc/systemd/system/my_app.service.d/.env

SECRET_KEY=somthing
SQL_ENGINE=somthing
SQL_DATABASE=somthing
SQL_USER=somthing
SQL_PASSWORD=somthing
SQL_HOST=somthing
SQL_PORT=somthing
DATABASE=somthing

Opened questions

  1. First if all, are there any obvious pitfalls?
  2. upgrade. Will restarting the service be enough to upgrade the application after a pip install --upgrade my_app?
  3. library conflicts Is it possible to make sure that gunicorn my_app.wsgi:application will use the correct versions of libraries used by the project? Or do I need to use a virtualenv? If so, should source /path/to/the/venv/bin/activate be used in ExecStart or is there a cleaner way to make sure ExecStart runs in a separate virtual environment?
  4. where should python manage.py migrate and python manage.py collectstatic live? Should I use those in /etc/systemd/system/my_app.service


Solution 1:[1]

Maybe you can try, but I'm also not sure if it works. This is for the third question.

You have to create a virtualenv, install gunicorn and django in it.

  1. Create a file python like this "gunicorn_config.py"
  2. Fill like this, or can be adjusted as needed:
#gunicorn_config.py

command = 'env/bin/gunicorn'

pythonpath = 'env/myproject'

bind = '127.0.0.1:8000'
  1. in the systemd ExecStart fill env/bin/gunicorn -c env/gunicorn_config.py myproject.wsgi.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 SalahAdDin