Production Behind a Proxy
Cheroot is a capable WSGI application server, but like Gunicorn or uWSGI it isn’t meant to face the public internet directly. The standard pattern is to put a reverse proxy in front of it to terminate TLS, serve static files, and forward dynamic requests to Cheroot.
1. Run Cheroot on a local port
Section titled “1. Run Cheroot on a local port”Bind Cheroot to localhost so only the proxy on the same host can reach it:
python manage.py cheroot --hostip 127.0.0.1 --port 8000 --minthreads 50 --maxthreads 100In a real deployment you’d run this under a process supervisor (systemd, Supervisor, or a container’s entrypoint) so it restarts on failure.
Example systemd unit
Section titled “Example systemd unit”[Unit]Description=MyProject (Django via Cheroot)After=network.target
[Service]User=www-dataWorkingDirectory=/srv/myprojectEnvironment=DJANGO_SETTINGS_MODULE=myproject.settingsExecStart=/srv/myproject/.venv/bin/python manage.py cheroot --hostip 127.0.0.1 --port 8000Restart=on-failure
[Install]WantedBy=multi-user.target2. Front it with nginx
Section titled “2. Front it with nginx”Let nginx terminate TLS, serve STATIC_ROOT directly, and proxy everything else to Cheroot:
server { listen 443 ssl; server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location /static/ { alias /srv/myproject/static/; }
location / { proxy_pass http://127.0.0.1:8000; 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; }}3. Collect static files
Section titled “3. Collect static files”nginx serves static assets, so build them once on deploy:
python manage.py collectstatic --noinputNext steps
Section titled “Next steps”- Custom thread pool — size the worker pool for your traffic.
- Configuration — the full option reference.