Development Long read Deployment
Correct Nginx + uWSGI setup

Correct Nginx + uWSGI setup

Reverse proxy, socket, and static file management.

24 February 2026 18 min read
Share
X in

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 = true

Nginx 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.

  1. Static dosyaları uWSGI'den ayırın
  2. gzip sıkıştırmayı etkinleştirin
  3. unix socket kullanın
  4. 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.