Table of Contents
What you will read?
- 1 Update the system and install prerequisites
- 2 Create a project directory and user (optional)
- 3 Create and activate a Python virtual environment
- 4 Install Django and start a project
- 5 Allow temporary test traffic (optional)
- 6 Configure Django for your domain and static files
- 7 Install Gunicorn and validate
- 8 Create a systemd service for Gunicorn
- 9 Configure Nginx as a reverse proxy
- 10 Harden the firewall for Nginx
- 11 Enable HTTPS with Let’s Encrypt (recommended)
- 12 Optional: PostgreSQL database setup
- 13 Verify logs and service health
Django runs well on Debian 13. The steps below install Python, isolate dependencies with a virtual environment, and serve your site via Gunicorn and Nginx. Commands assume sudo access on a clean server. Replace example.com and paths with your values. You’ll finish with a secure, production‑ready baseline.
Update the system and install prerequisites
Refresh package indexes and install Python, build tools, Nginx, and the firewall. This ensures a consistent base and modern toolchain.
sudo apt update
sudo apt -y upgrade
sudo apt -y install python3 python3-venv python3-pip python3-dev build-essential git nginx ufw
Create a project directory and user (optional)
Keep project files under /srv or /opt and optionally use a dedicated user for better isolation.
sudo adduser --system --group --home /srv/django mysite
sudo mkdir -p /srv/django/mysite
sudo chown -R mysite:mysite /srv/django/mysite
Create and activate a Python virtual environment
Use a virtual environment to avoid system-wide package conflicts and lock your app’s dependencies.
sudo -u mysite -H bash -c 'cd /srv/django/mysite && python3 -m venv venv'
sudo -u mysite -H bash -c 'source /srv/django/mysite/venv/bin/activate && pip install --upgrade pip setuptools wheel'
Install Django and start a project
Install Django via pip and generate a new project scaffold. Run a quick development server test.
sudo -u mysite -H bash -c 'source /srv/django/mysite/venv/bin/activate && pip install "Django>=4.2,<6"'
sudo -u mysite -H bash -c 'cd /srv/django/mysite && source venv/bin/activate && django-admin startproject config .'
sudo -u mysite -H bash -c 'cd /srv/django/mysite && source venv/bin/activate && python manage.py runserver 0.0.0.0:8000'
Example output:
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
Allow temporary test traffic (optional)
Open port 8000 only during testing, then close it to reduce exposure.
sudo ufw allow 8000/tcp
sudo ufw enable
sudo ufw status
Configure Django for your domain and static files
Set ALLOWED_HOSTS and a static collection path for production assets.
sudo sed -i "s/ALLOWED_HOSTS = .*/ALLOWED_HOSTS = ['example.com', 'www.example.com']/" /srv/django/mysite/config/settings.py
sudo bash -c 'cat >> /srv/django/mysite/config/settings.py <<EOF
from pathlib import Path
STATIC_ROOT = Path(BASE_DIR) / "staticfiles"
EOF'
sudo -u mysite -H bash -c 'cd /srv/django/mysite && source venv/bin/activate && python manage.py collectstatic --noinput'
Install Gunicorn and validate
Gunicorn is a robust WSGI HTTP server that runs Django behind Nginx. Validate it binds locally.
sudo -u mysite -H bash -c 'source /srv/django/mysite/venv/bin/activate && pip install gunicorn'
sudo -u mysite -H bash -c 'cd /srv/django/mysite && source venv/bin/activate && gunicorn config.wsgi:application --bind 127.0.0.1:8001'
Example output:
[INFO] Starting gunicorn...
[INFO] Listening at: http://127.0.0.1:8001 (pid: 12345)
Create a systemd service for Gunicorn
Run Gunicorn as a managed service that auto-starts on boot and restarts on failure.
sudo bash -c 'cat >/etc/systemd/system/gunicorn-mysite.service <<EOF
[Unit]
Description=Gunicorn for mysite
After=network.target
[Service]
User=mysite
Group=mysite
WorkingDirectory=/srv/django/mysite
Environment="PATH=/srv/django/mysite/venv/bin"
ExecStart=/srv/django/mysite/venv/bin/gunicorn --workers 3 --bind 127.0.0.1:8001 config.wsgi:application
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
EOF'
sudo systemctl daemon-reload
sudo systemctl enable --now gunicorn-mysite
sudo systemctl status gunicorn-mysite --no-pager
Configure Nginx as a reverse proxy
Proxy public traffic to Gunicorn and serve static assets efficiently.
sudo bash -c 'cat >/etc/nginx/sites-available/mysite <<EOF
server {
listen 80;
server_name example.com www.example.com;
client_max_body_size 20m;
location /static/ {
alias /srv/django/mysite/staticfiles/;
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8001;
}
}
EOF'
sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/mysite
sudo nginx -t
sudo systemctl restart nginx
Harden the firewall for Nginx
Allow HTTP/HTTPS and close the test port.
sudo ufw allow "Nginx Full"
sudo ufw delete allow 8000/tcp || true
sudo ufw status verbose
Enable HTTPS with Let’s Encrypt (recommended)
Issue a free TLS certificate and auto-renew it. Your DNS must point to the server.
sudo apt -y install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com --redirect -m [email protected] --agree-tos -n
sudo systemctl status certbot.timer --no-pager
Optional: PostgreSQL database setup
Install PostgreSQL, create a database and user, install the driver, then migrate.
sudo apt -y install postgresql postgresql-contrib libpq-dev
sudo -u postgres psql -c "CREATE USER mysite WITH PASSWORD 'StrongPass!';"
sudo -u postgres psql -c "CREATE DATABASE mysite OWNER mysite;"
sudo -u mysite -H bash -c 'source /srv/django/mysite/venv/bin/activate && pip install "psycopg2-binary<3.2"'
Update settings.py DATABASES, then migrate:
sudo -u mysite -H bash -c 'cd /srv/django/mysite && source venv/bin/activate && python manage.py migrate'
Verify logs and service health
Check service logs and ensure the stack is stable under systemd and Nginx.
sudo journalctl -u gunicorn-mysite -e --no-pager
sudo tail -n 100 /var/log/nginx/access.log
sudo tail -n 100 /var/log/nginx/error.log
Done. You now have Django running on Debian 13 behind Nginx with Gunicorn, static files collected, firewall locked down, and HTTPS ready. For more tutorials, guidance, and server purchases with support, visit dropvps.com.
