Introduction
The Nginx and uWSGI combination is the industry standard for Python web apps. Nginx handles TLS termination, static files, gzip, and rate limiting; uWSGI only processes dynamic WSGI requests.
This separation improves performance and security: Nginx manages high concurrency efficiently, uWSGI isolates the Python interpreter.
This guide covers unix socket connection, uwsgi_params, location blocks, and common error scenarios.
Unix Socket Connection
uWSGI creates a unix domain socket with socket = /run/uwsgi/app.sock. Nginx connects with uwsgi_pass unix:/run/uwsgi/app.sock;. Lower latency than TCP and security via filesystem permissions.
chmod-socket = 660 and chown-socket = www-data:www-data let nginx write to the socket. Create /run/uwsgi with systemd-tmpfiles.
[uwsgi]
socket = /run/uwsgi/myapp.sock
chmod-socket = 660
chown-socket = www-data:www-data
vacuum = trueNginx Location Configuration
The location / block forwards all dynamic requests to uWSGI. include uwsgi_params; sets standard CGI parameters. uwsgi_param SCRIPT_NAME /; matters for subdirectory deploys.
location /static/ alias /var/www/static/; serves static files directly from Nginx; never hits uWSGI.
- include uwsgi_params zorunlu
- static dosyaları Nginx'ten sunun
- upstream ile failover tanımlayın
- client_max_body_size upload limiti
upstream uwsgi_backend {
server unix:/run/uwsgi/myapp.sock;
}
server {
listen 80;
server_name example.com;
location /static/ { alias /var/www/static/; }
location / {
include uwsgi_params;
uwsgi_pass uwsgi_backend;
}
}SSL Termination
Define listen 443 ssl; and certificate paths in Nginx. uWSGI only receives HTTP; HTTPS terminates at Nginx. Forward X-Forwarded-Proto https via uwsgi_param.
Let's Encrypt certbot --nginx sets up automatic certificates and renewal. Django SECURE_PROXY_SSL_HEADER recognizes this header.
server {
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
include uwsgi_params;
uwsgi_param HTTPS on;
uwsgi_pass unix:/run/uwsgi/myapp.sock;
}
}Performance Tuning
Nginx worker_processes auto; and worker_connections 1024; handle high concurrency. Tune uwsgi_buffers and uwsgi_buffer_size for large responses.
gzip on; and gzip_types text/css application/javascript; save bandwidth. On uWSGI side post-buffering buffers large POST requests.
- Static dosyaları uWSGI'den ayırın
- gzip sıkıştırmayı etkinleştirin
- unix socket kullanın
- worker sayısını CPU'ya göre ayarlayın
Troubleshooting
502 Bad Gateway usually means socket permission error or uWSGI not running. Check socket with ls -la /run/uwsgi/. Search uwsgi.log for import errors.
504 Gateway Timeout is uWSGI harakiri or Nginx proxy_read_timeout exceeded. Align timeout values on both sides.
# Nginx timeout ayarları
uwsgi_read_timeout 60;
uwsgi_send_timeout 60;
proxy_read_timeout 60;Static dosyaları asla uWSGI'ye yönlendirmeyin; bu en yaygın performans hatasıdır.
In Docker
In Docker Compose nginx and uwsgi are separate services; mount socket via shared volume. /run/uwsgi volume must use the same path in both containers.
Alternatively use internal TCP (uwsgi_pass 172.x.x.x:8000); not as fast as unix socket but avoids volume sharing.
services:
uwsgi:
volumes: ["socket:/run/uwsgi"]
nginx:
volumes: ["socket:/run/uwsgi"]
volumes:
socket:Conclusion
Properly configured Nginx + uWSGI forms a high-performance, secure production stack. Static/dynamic split, unix socket, and SSL termination are the core trio.
Manage configs as infrastructure-as-code; validate every change in staging with nginx -t and uwsgi --ini.