How to Set Up a Python Virtual Environment on Debian 10 Buster - LinuxConfig.org

There are two very simple ways to create a Python virtual environment on Debian 10. They're very similar and offer nearly the same benefits. As an added bonus, you won't need to install anything outside of the default Debian repositories to use them.


This is a companion discussion topic for the original entry at https://linuxconfig.org/how-to-set-up-a-python-virtual-environment-on-debian-10-buster

I followed this recently. It is unfortunately missing configuring systemd to launch the application.

I’ll post here what I find, this would be a very good addition to the article.

Sounds like a plan…thank you

Alright

  1. add the user

sudo useradd -s /usr/sbin/nologin -r -M django

  1. chown the project

sudo chown -R django:django /srv/django

  1. Create the service file

sudo vi /etc/systemd/system/django.service

Contents of the file:

[Unit]
Description=django
Wants=network-online.target
After=network-online.target

[Service]
User=django
Group=django
Type=simple
WorkingDirectory=/srv/django
ExecStart=/srv/django/bin/python3 /srv/django/manage.py runserver 0.0.0.0:8000

[Install]
WantedBy=multi-user.target

Actually the above isn’t best practice.

runserver is for developing. by the time you need systemd you should be using SSL and a WSGI.

I’m determining now if gunicorn or one of the other frameworks is best for my use case.

Ok I went with gunicorn. Seems like most would

  1. ensure all you project dependencies are actually installed in the virtualenv
    inside your project and install gunicorm

pip install -I -r requirements.txt
sudo pip install gunicorn

  1. create interdependent services for gunicorn and it’s socket

vi /etc/systemd/system/gunicorn.service
[Unit]
Description=Gunicorn instance to serve django
Requires=/gunicorn.socket
After=network-online.target

[Service]
Type=notify
User=django
Group=django
RuntimeDirectory=gunicorn
WorkingDirectory=/srv/django
ExecStart=/usr/local/bin/gunicorn django.wsgi
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true

[Install]
WantedBy=multi-user.target

vi /etc/systemd/system/django.socket
[Unit]
Description=django.socket

[Socket]
ListenStream=/run/django.sock
User=django

[Install]
WantedBy=sockets.target

  1. Config nginx; not covering install and setting up certs etc, just the config as it’s django specific

vi /etc/nginx/sites-available/django
server {
listen 80;
server_name django.yourdomain;
return 301 https://$server_name$request_uri;
}

server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/certs/star_yourdomain.pem;
ssl_certificate_key /etc/nginx/ssl/private/star_yourdomain.key;

server_name django.yourdomain.net;    

location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass  http://unix:/run/django.sock;
}

}