3.1 KiB
aliases, up, tags
| aliases | up | tags | |
|---|---|---|---|
| 00_devop_note |
|
What is uWSGI?
uWSGI is an application server that sits between a web server (like Nginx or Apache) and a Python web application (like Django, Flask, or FastAPI). It runs your Python code and handles incoming web requests.
The name comes from WSGI (Web Server Gateway Interface), which is the standard Python spec (PEP 3333) that defines how web servers talk to Python applications. The lowercase "u" is the Greek letter μ (micro), suggesting it's lightweight — though in practice it grew into a full-featured server.
Why do we need it?
A plain web server like Nginx doesn't know how to execute Python code. It only serves static files (HTML, CSS, images) and forwards dynamic requests elsewhere. You need a process that:
- Loads your Python application into memory
- Receives requests from the web server
- Calls your Python code with the request
- Returns the response back to the web server
That middle process is uWSGI (or alternatives like Gunicorn).
The typical stack
Browser → Nginx → uWSGI → Python app (Django/Flask)
- Nginx: handles SSL, static files, load balancing, gzip, caching
- uWSGI: runs Python workers, manages processes/threads
- Python app: your business logic
Nginx and uWSGI usually talk over a Unix socket (fast, local) or a TCP port. The protocol between them is called the uwsgi protocol (lowercase) — a binary protocol that's faster than plain HTTP.
Key features
- Process management: spawns multiple worker processes to handle concurrent requests
- Threading: each worker can run multiple threads
- Auto-reload: restart workers when code changes (dev mode)
- Emperor mode: one master process supervising many vassal apps
- Cheaper mode: dynamically scale workers up/down based on load
- Multi-language: despite the name, also supports Ruby, Perl, Go, etc.
Minimal config example
A typical uwsgi.ini:
[uwsgi]
module = myproject.wsgi:application
master = true
processes = 4
threads = 2
socket = /tmp/myproject.sock
chmod-socket = 660
vacuum = true
die-on-term = true
module: entry point (the WSGI callable)processes: how many worker processes to forksocket: where Nginx connects tovacuum: clean up the socket on exitdie-on-term: shut down cleanly on SIGTERM
Running it
uwsgi --ini uwsgi.ini
Or in production, run it under systemd so it restarts on failure.
uWSGI vs Gunicorn
Both are WSGI servers. The community has largely shifted toward Gunicorn because:
- Simpler config
- Fewer footguns
- Easier to deploy
uWSGI is more feature-rich and faster in some benchmarks, but its config surface is huge (hundreds of options) and the project has had governance/maintenance concerns. For new projects, Gunicorn behind Nginx is the common default.
When you'll see uWSGI
- Legacy Django/Flask deployments
- Setups that need uWSGI-specific features (Emperor, cheaper, etc.)
- Docker images for older Python web apps
Related
- Apache Tomcat — the Java equivalent role (servlet container running Java apps behind a web server)