uWSGI’s Built-In HTTPS Server: Let’s Encrypt Reloads in One Binary
uWSGI can serve HTTPS directly and auto-reload Let’s Encrypt certificates with --http-ssl-reload. Learn how to configure, verify, and when this single-binary approach is right for you.
13 May 2026, 23:16 UTC

Why a Single-Binary HTTPS Server Matters
Deploying a Python web app often feels like juggling three tools: a WSGI server, a reverse proxy, and an SSL terminator. For small sites or prototypes, that overhead can be a waste of time. uWSGI’s built-in HTTP/HTTPS server lets you skip the proxy entirely, handling SSL termination and request routing inside the same process. The twist? It can automatically reload Let’s Encrypt certificates when they’re renewed, keeping the server live without a manual restart.
Thesis: uWSGI’s HTTP Server is a "Good Enough" Choice for Low-to-Medium Traffic
When traffic stays below a few thousand concurrent connections, the convenience of a single binary outweighs the performance penalties of uWSGI’s event-loop design. The ability to auto-reload certificates removes the need for complex cron jobs or external scripts that touch the process.
Configuring uWSGI for Let’s Encrypt
Below is a minimal command line that spins up uWSGI with HTTPS on port 8443, pointing to a Certbot-managed certificate directory. Replace example.com with your domain.
uwsgi \
--http-socket 0.0.0.0:8443 \
--module myapp:app \
--http-ssl-certificate /etc/letsencrypt/live/example.com/fullchain.pem \
--http-ssl-key /etc/letsencrypt/live/example.com/privkey.pem \
--http-ssl-reload \
--processes 4 \
--threads 2 \
--logto /var/log/uwsgi/myapp.log
Key configuration points:
--http-socket: Starts the built-in HTTP server.- SSL files: These are taken directly from Certbot’s live directory.
--http-ssl-reload: Watches the key and certificate for changes and reloads the socket without killing workers.--processesand--threads: Tune these to manage concurrency.
Lazy Loading & Memory Footprint
uWSGI’s --module and --callable options enable lazy loading, delaying the import of the application until the first request. This keeps the initial memory usage low, which is useful when running multiple apps on the same host.
Concrete Example: "Hello, World" App
Assume myapp.py contains the following WSGI application:
def app(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
return [b'Hello, World']
Running the command above will expose https://localhost:8443 with a valid Let's Encrypt certificate. A simple curl -I https://localhost:8443 should return a 200 OK header and an HTTP/1.1 protocol line.
Trade-offs & Limitations
- No HTTP/2: uWSGI’s server only speaks HTTP/1.1. Clients expecting HTTP/2 will fall back, potentially hurting throughput for streaming or large API responses.
- Event-loop scaling: Each worker runs its own event loop. Under high concurrency (tens of thousands of connections), the server can become a bottleneck compared to Nginx or Caddy.
- File-system permissions: The
--http-ssl-reloadflag requires read/write access to the certificate directory. If the uWSGI process runs as a privileged user, this can open a privilege-escalation vector if not properly confined. - Limited HTTP features: Advanced features like server push or sophisticated load balancing are absent. For complex architectures, a reverse proxy remains the safer bet.
Verification Checklist
- SSL Handshake: Run
openssl s_client -connect localhost:8443 -tls1_2and confirm the server presentsfullchain.pemand the subject matches your domain. - Reload Trigger: Touch the key file (
touch /etc/letsencrypt/live/example.com/privkey.pem) and watch the uWSGI log for a reload message. - Protocol Check: Use
curl -Ito confirm the protocol isHTTP/1.1, as HTTP/2 is not supported.
Actionable Takeaway
If your deployment is small, static-content light, or you need a quick, self-contained server for a dev environment, uWSGI’s built-in HTTPS server with --http-ssl-reload is a solid choice. For anything that exceeds a few thousand concurrent connections or requires HTTP/2, wrap uWSGI behind Nginx or Caddy and let the proxy handle SSL.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.