NGINX Reverse Proxy and Sidecar Pattern
NGINX Reverse Proxy and Sidecar Pattern
This is the routing pattern I ended up trusting for isolated app workloads on one VPS.
Internet
-> public gateway
-> environment proxy on host loopback
-> sidecar inside the app pod
-> app bound to container loopback
The important part is the boundary at each hop:
- the public gateway only terminates TLS and forwards accepted hostnames
- the environment proxy only publishes to host loopback
- the sidecar is the only component allowed to reach the app over namespace-local loopback
- the app itself is never directly exposed
Why this pattern held up
It gave me three things I wanted at the same time:
- per-environment routing without a shared cross-pod network
- simple health checks at every layer
- failure isolation that is easier to reason about than one giant NGINX setup
The sidecar model matters because it keeps the application private while still giving the proxy chain a stable HTTP entry point. The rootless environment proxy matters because it keeps the published surface narrow and local to the host.
The key lesson
The main operational lesson was about namespace ownership.
If the sidecar uses network_mode: "service:<app>", the app service owns the network namespace. That means published ports must live on the app service, not on
the sidecar. Once that was clear, the 502-style confusion stopped.
Why I kept it
I kept this pattern because it is explicit.
When something breaks, I can test:
- the gateway
- the environment proxy
- the sidecar
- the app
in that order, with a separate health signal at each hop. That is a much better operational shape than debugging one large proxy layer with unclear boundaries.