Docker nginx reverse proxy gives 502 Bad Gateway
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
A 502 Bad Gateway from Nginx means Nginx received the client request but could not get a valid response from the upstream application. In Docker setups, that usually comes down to the reverse proxy pointing at the wrong host or port, the backend container not being reachable on the Docker network, or the app not being ready when Nginx starts forwarding traffic.
What Nginx Is Actually Trying to Reach
Inside a container, localhost means the container itself, not another service. That is the first thing to check.
If Nginx is in one container and your application is in another, this is wrong:
That tells the Nginx container to connect back to itself. In Docker Compose, you usually want the service name instead:
The app hostname works because Docker Compose provides service-name DNS on the shared network.
A Minimal Working Compose Setup
A simple example makes the networking model clearer:
And the sample backend:
The important detail is that the app listens on 0.0.0.0, not only on 127.0.0.1. If it binds only to loopback inside its own container, other containers cannot reach it.
How to Debug the Failure Quickly
Start with the basics:
Then test connectivity from inside the Nginx container:
If that curl request fails, Nginx is not the problem. The issue is the app container, port, bind address, or shared network.
Also validate the Nginx config before restarting it:
That catches syntax errors and invalid upstream configuration immediately.
Readiness and Startup Order
depends_on only controls container start order. It does not guarantee the application is ready to accept traffic. A backend that takes ten seconds to boot can still produce temporary 502 responses while Nginx is already live.
In those cases, the fix is usually one of these:
- add a health check and wait for readiness
- make the app start faster
- configure retries at the right layer
Do not assume that because Docker started the container, the service inside it is listening.
Common Pitfalls
The most common mistake is using localhost in proxy_pass. In a multi-container setup, use the backend service name instead.
Another common issue is pointing Nginx at the host-exposed port instead of the container's internal listening port. Nginx talks to the backend over the Docker network, so it needs the container port, not the published host port.
People also forget the backend bind address. A service listening only on 127.0.0.1 inside its own container will appear healthy from its own logs but remain unreachable from Nginx.
Finally, treat depends_on as ordering, not readiness. If the backend is booting, crashing, or restarting, Nginx can only report the upstream failure.
Summary
- A Docker Nginx
502usually means the reverse proxy cannot reach a healthy upstream. - Use the backend service name in
proxy_pass, notlocalhost. - Make sure the application listens on
0.0.0.0and on the expected internal port. - Debug from inside the Nginx container with
curland validate config withnginx -t. - Remember that container startup order is not the same as application readiness.

