Django Deployment with NGINX proxy
What we'll do in this consideration is deploy nginx with a debian host and enable configurations and components to change when we change debug = False. Going to production with gunicorn contains a plethora of boobytraps, obsfucation, and a ton of needless work.
What we need:
nginx.conf
forhost_2
- Serves
/media/
files locally - Proxies all other requests to Gunicorn (running on
localhost:8000
)
# /etc/nginx/sites-available/myapp server { listen 80; server_name _; # wildcard for internal/border routing access_log /var/log/nginx/app.access.log; error_log /var/log/nginx/app.error.log; # Serve media files directly location /media/ { alias /srv/myapp/media/; autoindex off; expires 30d; add_header Cache-Control "public"; } # Pass everything else to Gunicorn location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_redirect off; } } ```
- enable the config:
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx
- Required Django
settings.py
lines
import os DEBUG = False ALLOWED_HOSTS = ['yourdomain.com', 'ip.address.goes.here'] # internal IP or hostname # Let Django trust the X-Forwarded-Proto header for HTTPS SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') USE_X_FORWARDED_HOST = True # Media settings MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # or /srv/myapp/media
systemd:
# /etc/systemd/system/gunicorn.service [Unit] Description=gunicorn daemon After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/srv/myapp ExecStart=/srv/myapp/venv/bin/gunicorn yourproject.wsgi:application \ --bind 127.0.0.1:8000 \ --workers 3 [Install] WantedBy=multi-user.target
- do the needful
sudo systemctl daemon-reexec sudo systemctl enable gunicorn sudo systemctl start gunicorn
- Auto-starting
nginx
in production (DEBUG=False
)
#!/bin/bash if grep -q "DEBUG = False" /srv/myapp/yourproject/settings.py; then sudo systemctl restart nginx fi
- Media serving setup
Comments
-
Update: The same but similar problem remains present despite a series of new steps in troubleshooting.
I have a debugger inline so I can write tests for the debugger.
There is also a development machine with True if you want to see what the rendered components 'should' look like
to run: gunicorn -c /client/utils/gunicorn_conf.py backend.wsgi
|-- code | |-- README.md | |-- access.log | |-- backend | |-- client | |-- db.sqlite3 | |-- error.log | |-- inventory | |-- manage.py | |-- media | `-- requirements.txt |-- html | |-- media | `-- static |-- logs | `-- error.log `-- server.sock
# Allow gzip compression gzip_types text/css application/json appli cation/x-javascript; gzip_comp_level 6; gzip_proxied any; # Look for files with .gz to serve pre-com pressed data gzip_static on; # Where to look for content (static an d media) root /srv/www/html/;
-
html/ |-- media | `-- featured_cards `-- static |-- admin |-- images |-- styles.css |-- styles.css.gz |-- table_style.css `-- table_style.css.gz * gunicorn.service - gunicorn daemon Loaded: loaded (/etc/systemd/system/gunicorn.service; enabled; vendor preset: enabled) Active: active (running) since Sun 2025-06-22 06:11:32 UTC; 7min ago Main PID: 7455 (gunicorn) Tasks: 4 (limit: 38149) Memory: 164.7M CPU: 1.610s CGroup: /system.slice/gunicorn.service |-7455 /srv/www/.venv/bin/python3 /srv/www/.venv/bin/gunicorn backend.wsgi:application > |-7457 /srv/www/.venv/bin/python3 /srv/www/.venv/bin/gunicorn backend.wsgi:application > |-7458 /srv/www/.venv/bin/python3 /srv/www/.venv/bin/gunicorn backend.wsgi:application > `-7459 /srv/www/.venv/bin/python3 /srv/www/.venv/bin/gunicorn backend.wsgi:application >
Howdy, Stranger!