Mistake #1 — Forgetting WebSocket Support
Many modern applications rely on WebSockets:
Next.js development serversOpenClawAI dashboardsReal-time chat systemsMonitoring toolsA typical broken configuration looks like:
location / {
proxy_pass http://localhost:3000;
}
The application loads.
Then WebSockets silently fail.
Fix
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Without these headers, real-time features often stop working.
---
Mistake #2 — Losing the Real Client IP
By default, many applications only see:
instead of the visitor's actual IP.
This breaks:
Rate limitingSecurity monitoringAudit logsGeo-blockingAnalyticsWrong
location / {
proxy_pass http://localhost:3000;
}
Correct
location / {
proxy_pass http://localhost:3000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Now your application receives the real visitor address.
---
Mistake #3 — Missing Host Headers
Many applications depend on the original hostname.
Examples:
NextAuthOAuth providersOpenID ConnectMulti-domain SaaS platformsWithout the Host header, authentication may fail unexpectedly.
Fix
proxy_set_header Host $host;
A complete configuration often includes:
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
---
Mistake #4 — Creating Infinite Redirect Loops
A common HTTPS setup mistake:
server {
listen 443 ssl;
location / {
proxy_pass http://localhost:3000;
}
}
The application thinks it is running on HTTP.
It redirects to HTTPS.
Nginx receives HTTPS.
The application redirects again.
Welcome to an infinite loop.
Fix
proxy_set_header X-Forwarded-Proto $scheme;
Many frameworks rely on this header to detect HTTPS correctly.
---
Mistake #5 — Too Small Upload Limits
Everything works.
Until someone uploads a file.
Suddenly:
413 Request Entity Too Large
appears.
The default upload limit is often far too small for modern applications.
Fix
client_max_body_size 500M;
For media-heavy projects:
may be more appropriate.
---
Mistake #6 — Using localhost Incorrectly with Docker
One of the most common Docker mistakes.
You configure:
proxy_pass http://localhost:3000;
But Nginx runs in a container.
The application runs in another container.
For Nginx:
not your application.
Fix
Use the Docker service name:
proxy_pass http://app:3000;
where app is the container name defined in Docker Compose.
---
Mistake #7 — Timeouts That Kill Long Requests
Modern AI applications often take longer to respond.
Examples:
LLM inferenceImage generationVideo processingDatabase exportsDefault timeouts can terminate requests early.
Fix
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
For local AI servers, even higher values may be necessary.
---
Mistake #8 — Not Forwarding Authentication Headers
Applications using:
JWT tokensAPI keysBearer authenticationcan fail mysteriously if headers are stripped.
Ensure Nginx passes them through:
proxy_set_header Authorization $http_authorization;
Without this, APIs may reject valid requests.
---
Mistake #9 — Ignoring Nginx Error Logs
Many administrators immediately inspect application logs.
The actual answer is often sitting in:
sudo tail -f /var/log/nginx/error.log
Typical messages include:
upstream timed out
connection refused
no live upstreams
host not found
These logs frequently reveal the root cause within seconds.
---
Mistake #10 — Proxying Before Testing Locally
One of the biggest deployment mistakes:
Configure Nginx first.
Debug later.
Always verify the application directly.
Example:
curl http://localhost:3000
If the application doesn't work locally, Nginx cannot fix it.
Verify:
1. Application running
2. Port accessible
3. Correct response returned
4. Then add Nginx
This simple habit saves hours of troubleshooting.
---
Recommended Production Template
A safe baseline configuration for many Node.js applications:
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
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;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 300;
proxy_send_timeout 300;
}
This covers the majority of deployment scenarios involving Next.js, Docker, WebSockets, and self-hosted services.
Final Thoughts
Nginx is rarely the problem itself.
The problem is usually a missing header, a timeout value, or an incorrect assumption about how reverse proxies work.
When applications suddenly stop authenticating, WebSockets disconnect, or Docker deployments return mysterious 502 errors, reviewing your reverse proxy configuration should be one of the first troubleshooting steps.
A properly configured Nginx reverse proxy is almost invisible. A misconfigured one can take an entire application offline.