Deploying a Django application to production can be tricky. This guide covers the full stack: Ubuntu, PostgreSQL, Gunicorn, Nginx, and SSL.
Prerequisites
- A VPS with Ubuntu 22.04+ (minimum 2GB RAM recommended)
- A domain pointed to your server's IP
- SSH access
Step 1: Install Dependencies
sudo apt update && sudo apt upgrade -ychr(10)sudo apt install python3 python3-pip python3-venv nginx postgresql postgresql-contrib -yStep 2: Create Database
sudo -u postgres psqlchr(10)CREATE DATABASE yourproject;chr(10)CREATE USER youruser WITH PASSWORD 'securepassword';chr(10)ALTER ROLE youruser SET client_encoding TO 'utf8';chr(10)ALTER ROLE youruser SET default_transaction_isolation TO 'read committed';chr(10)GRANT ALL PRIVILEGES ON DATABASE yourproject TO youruser;chr(10)\qStep 3: Set Up Your Project
cd /var/wwwchr(10)git clone your-repo-url yourprojectchr(10)cd yourprojectchr(10)python3 -m venv venvchr(10)source venv/bin/activatechr(10)pip install -r requirements.txtchr(10)pip install gunicornUpdate settings.py: set DEBUG = False, configure ALLOWED_HOSTS, set database credentials, and set STATIC_ROOT.
python manage.py migratechr(10)python manage.py collectstatic --no-inputchr(10)python manage.py createsuperuserStep 4: Configure Gunicorn
Create /etc/systemd/system/yourproject.service:
[Unit]chr(10)Description=Gunicorn for yourprojectchr(10)After=network.targetchr(10)chr(10)[Service]chr(10)User=www-datachr(10)Group=www-datachr(10)WorkingDirectory=/var/www/yourprojectchr(10)ExecStart=/var/www/yourproject/venv/bin/gunicorn --workers 3 --bind unix:/var/www/yourproject/gunicorn.sock yourproject.wsgi:applicationchr(10)chr(10)[Install]chr(10)WantedBy=multi-user.targetsudo systemctl start yourprojectchr(10)sudo systemctl enable yourprojectStep 5: Configure Nginx
Create /etc/nginx/sites-available/yourproject:
server {chr(10)listen 80;chr(10)server_name yourdomain.com www.yourdomain.com;chr(10)chr(10)location /static/ {chr(10)alias /var/www/yourproject/staticfiles/;chr(10)}chr(10)chr(10)location /media/ {chr(10)alias /var/www/yourproject/media/;chr(10)}chr(10)chr(10)location / {chr(10)proxy_pass http://unix:/var/www/yourproject/gunicorn.sock;chr(10)proxy_set_header Host $host;chr(10)proxy_set_header X-Real-IP $remote_addr;chr(10)proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;chr(10)proxy_set_header X-Forwarded-Proto $scheme;chr(10)}chr(10)}sudo ln -s /etc/nginx/sites-available/yourproject /etc/nginx/sites-enabled/chr(10)sudo nginx -tchr(10)sudo systemctl restart nginxStep 6: SSL with Let's Encrypt
sudo apt install certbot python3-certbot-nginxchr(10)sudo certbot --nginx -d yourdomain.com -d www.yourdomain.comCommon Errors
- 502 Bad Gateway — Gunicorn isn't running or socket path is wrong
- Static files missing — Run
collectstaticand checkSTATIC_ROOT - Database errors — Check PostgreSQL credentials and permissions
- Permission denied — Ensure www-data owns the project directory