Python with Gunicorn (Flask / Django)
Gunicorn is the standard WSGI server for Python applications (Flask, Django, FastAPI). Nginx acts as a reverse proxy in front of Gunicorn, handling HTTPS and static files.
02
Install Python and dependencies
bash
# Python 3 is already included in Ubuntu/Debian
python3 --version
# Install pip and venv
apt install python3-pip python3-venv -y
03
Recommended project structure
/var/www/my-app/
├── app.py (or wsgi.py)
├── requirements.txt
├── venv/
└── ...
04
Application setup
bash
# Create the directory
mkdir -p /var/www/my-app
cd /var/www/my-app
# Copy your project (or clone from git)
git clone https://github.com/user/project.git .
# Create a virtual environment
python3 -m venv venv
# Activate the virtual environment
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Install Gunicorn in the virtual environment
pip install gunicorn
05
Test Gunicorn
Flask
bash
# If your file is called app.py and the Flask instance is 'app'
gunicorn --bind 0.0.0.0:8000 app:app
Django
bash
# Replace 'myproject' with the name of your Django project
gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application
If the site responds on http://IP:8000, Gunicorn works. Now configure it as a service.
06
systemd service for Gunicorn
bash
nano /etc/systemd/system/my-app.service
Flask
ini
[Unit]
Description=Gunicorn for my Flask app
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/my-app
Environment="PATH=/var/www/my-app/venv/bin"
ExecStart=/var/www/my-app/venv/bin/gunicorn \
--workers 3 \
--bind unix:/run/my-app.sock \
--access-logfile /var/log/gunicorn/my-app-access.log \
--error-logfile /var/log/gunicorn/my-app-error.log \
app:app
Restart=always
[Install]
WantedBy=multi-user.target
Django
ini
[Unit]
Description=Gunicorn for my Django app
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/my-app
Environment="PATH=/var/www/my-app/venv/bin"
ExecStart=/var/www/my-app/venv/bin/gunicorn \
--workers 3 \
--bind unix:/run/my-app.sock \
--access-logfile /var/log/gunicorn/my-app-access.log \
--error-logfile /var/log/gunicorn/my-app-error.log \
myproject.wsgi:application
Restart=always
[Install]
WantedBy=multi-user.target
bash
mkdir -p /var/log/gunicorn
chown -R www-data:www-data /var/www/my-app /var/log/gunicorn
systemctl daemon-reload
systemctl enable --now my-app
systemctl status my-app
07
Nginx configuration as reverse proxy
bash
nano /etc/nginx/sites-available/my-app
nginx
server {
listen 80;
server_name example.com www.example.com;
# Static files (Django: served by Nginx, not Gunicorn)
location /static/ {
alias /var/www/my-app/staticfiles/;
}
location /media/ {
alias /var/www/my-app/media/;
}
location / {
proxy_pass http://unix:/run/my-app.sock;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 90s;
}
}
bash
ln -s /etc/nginx/sites-available/my-app /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
# Add SSL
certbot --nginx -d example.com -d www.example.com
08
How many Gunicorn workers to use?
The recommended formula is: (2 × number_of_cores) + 1
bash
# See how many cores your server has
nproc
# Example: 2 cores → 5 workers
# Example: 4 cores → 9 workers
ini
ExecStart=... gunicorn --workers 5 ...
09
Environment variables
Never put secrets in code. Use them via the systemd service:
ini
[Service]
Environment="DATABASE_URL=postgresql://user:pass@localhost/db"
Environment="SECRET_KEY=long-secret-key"
Environment="DEBUG=False"
Or via a .env file (requires python-dotenv):
ini
EnvironmentFile=/var/www/my-app/.env
10
Update the application
bash
cd /var/www/my-app
git pull origin main
source venv/bin/activate
pip install -r requirements.txt
# Django: migrate database and collect static files
python manage.py migrate
python manage.py collectstatic --noinput
# Restart Gunicorn
systemctl restart my-app
Articoli correlati
Software
Package Installation
How to install, update and remove software on your Linux server
2 min di lettura
Software
Web Server: Nginx
Installation and basic configuration of Nginx on your server
2 min di lettura
Software
Web Server: Apache
Installation and basic configuration of Apache on your server
2 min di lettura
