How to Use Nginx with FastAPI for Production Deployment
To use
nginx with FastAPI, run your FastAPI app with an ASGI server like uvicorn on a local port, then configure nginx as a reverse proxy to forward HTTP requests to that port. This setup improves performance, security, and allows handling static files and HTTPS easily.Syntax
Here is the basic syntax to configure nginx as a reverse proxy for a FastAPI app running on localhost port 8000:
- server: Defines the server block for your domain or IP.
- listen: The port
nginxlistens on, usually 80 for HTTP. - location /: Matches all requests and proxies them.
- proxy_pass: Forwards requests to the FastAPI app URL.
- proxy_set_header: Passes headers to preserve client info.
nginx
server {
listen 80;
server_name your_domain.com;
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;
}
}Example
This example shows a complete FastAPI app running with uvicorn and an nginx config to serve it on port 80. It demonstrates how requests to http://your_domain.com/ reach the FastAPI app.
python + nginx
# fastapi_app.py from fastapi import FastAPI app = FastAPI() @app.get("/") async def read_root(): return {"message": "Hello from FastAPI behind Nginx!"} # Run the app with: # uvicorn fastapi_app:app --host 127.0.0.1 --port 8000 # nginx config (e.g., /etc/nginx/sites-available/fastapi): server { listen 80; server_name your_domain.com; 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; } } # After saving nginx config, reload nginx with: # sudo nginx -s reload
Output
When you visit http://your_domain.com/ in a browser, you will see JSON output: {"message": "Hello from FastAPI behind Nginx!"}
Common Pitfalls
Common mistakes when using nginx with FastAPI include:
- Not running the FastAPI app on the same host and port as
nginxexpects. - Forgetting to set
proxy_set_headerdirectives, which can cause issues with client IP or HTTPS detection. - Not reloading
nginxafter changing the config. - Trying to serve static files through FastAPI instead of letting
nginxhandle them for better performance.
Example of a wrong and right nginx proxy config:
nginx
# Wrong: Missing proxy headers
server {
listen 80;
server_name your_domain.com;
location / {
proxy_pass http://127.0.0.1:8000;
}
}
# Right: With proxy headers
server {
listen 80;
server_name your_domain.com;
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;
}
}Quick Reference
| Directive | Purpose |
|---|---|
| listen 80; | Listen on HTTP port 80 |
| server_name your_domain.com; | Domain or IP address to serve |
| location / { ... } | Match all requests to proxy |
| proxy_pass http://127.0.0.1:8000; | Forward requests to FastAPI app |
| proxy_set_header Host $host; | Preserve original Host header |
| proxy_set_header X-Real-IP $remote_addr; | Pass client IP to app |
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | Chain client IPs through proxies |
| proxy_set_header X-Forwarded-Proto $scheme; | Pass HTTP or HTTPS scheme |
Key Takeaways
Run FastAPI with uvicorn on a local port before proxying with nginx.
Configure nginx as a reverse proxy with proper proxy headers for client info.
Reload nginx after config changes to apply them.
Use nginx to serve static files for better performance, not FastAPI.
Test your setup by visiting your domain to see FastAPI responses through nginx.