Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/astrxnomo/shop-microservers/llms.txt

Use this file to discover all available pages before exploring further.

The Nginx gateway is the unified entry point for every request in Shop Microservers. Clients — whether a browser, the Next.js frontend, or an API tool — connect to a single address on port 80. Nginx inspects the URL prefix and forwards the request to the appropriate upstream container over Docker’s internal network. This design keeps all microservices off the public network, normalizes host headers, and provides a convenient /health endpoint used by Docker Compose to verify the gateway itself is alive before marking the stack as ready.

Overview

Container

Built from ./gateway/Dockerfile. Listens on port 80 (configurable via GATEWAY_PORT in docker-compose.yml).

Role

Single entry point for all client traffic. Routes by URL prefix to the appropriate upstream service.

DNS Resolver

Uses Docker’s embedded DNS at 127.0.0.11 with a 30s valid TTL so upstream containers can be resolved by their service name.

Startup Order

The gateway container only starts after all four microservices pass their own /health checks, enforced via depends_on in docker-compose.yml.

Routing Table

All traffic enters through port 80. Nginx strips the matching location prefix and proxies the remainder to the upstream.
Path PrefixUpstream NameInternal Address
/api/auth/auth_serviceauth:3004
/api/catalog/catalog_servicecatalog:3001
/api/cart/cart_servicecart:3002
/api/orders/orders_serviceorders:3003
/frontend_appfrontend:3000
/health(inline)Returns 200 ok
Because each location uses proxy_pass http://upstream_name/, the path prefix is stripped before forwarding. A request to /api/auth/login reaches the auth service as /login.

nginx.conf

events {
  worker_connections 1024;
}

http {
  resolver 127.0.0.11 valid=30s;

  upstream auth_service    { server auth:3004;    }
  upstream catalog_service { server catalog:3001; }
  upstream cart_service    { server cart:3002;    }
  upstream orders_service  { server orders:3003;  }
  upstream frontend_app    { server frontend:3000; }

  server {
    listen 80;

    location = /health {
      return 200 'ok';
      add_header Content-Type text/plain;
    }

    location /api/auth/ {
      proxy_pass         http://auth_service/;
      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;
    }

    location /api/catalog/ {
      proxy_pass         http://catalog_service/;
      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;
    }

    location /api/cart/ {
      proxy_pass         http://cart_service/;
      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;
    }

    location /api/orders/ {
      proxy_pass         http://orders_service/;
      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;
    }

    location / {
      proxy_pass         http://frontend_app;
      proxy_http_version 1.1;
      proxy_set_header   Upgrade $http_upgrade;
      proxy_set_header   Connection 'upgrade';
      proxy_set_header   Host $host;
      proxy_cache_bypass $http_upgrade;
    }
  }
}

WebSocket Support

The catch-all location / block that forwards to the Next.js frontend includes WebSocket upgrade headers:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;
These are required for Next.js Hot Module Replacement (HMR) to function in development mode. Without them, the WebSocket connection the browser tries to open for HMR would be rejected by Nginx.
In production builds, HMR is not used and these headers have no effect — they are safe to leave in place for both environments.

Health Endpoint

The gateway exposes a dedicated health check at GET /health:
location = /health {
  return 200 'ok';
  add_header Content-Type text/plain;
}
This returns 200 OK with the plain-text body ok without touching any upstream. It is used by Docker Compose healthcheck configurations to determine whether the gateway container is ready to accept traffic.
curl http://localhost/health
# ok

DNS Resolution

resolver 127.0.0.11 valid=30s;
127.0.0.11 is Docker’s embedded DNS server. Setting valid=30s tells Nginx to re-resolve upstream hostnames every 30 seconds, which is important during rolling restarts: if a service container is replaced, Nginx will pick up the new IP within 30 seconds rather than caching a stale address indefinitely.

Startup Dependencies

The gateway does not start until all four microservices (auth, catalog, cart, orders) report healthy via their own /health endpoints. This is enforced by depends_on with condition: service_healthy in docker-compose.yml. If any microservice fails its health check, the gateway will not start and Nginx will not be reachable.

Forwarded Headers

Every proxied request receives three additional headers set by Nginx:
HeaderValuePurpose
Host$hostPreserves the original Host header
X-Real-IP$remote_addrThe client’s true IP address
X-Forwarded-For$proxy_add_x_forwarded_forAppended IP chain for multi-hop proxies
These headers allow microservices to log real client IPs even though they only receive connections from Nginx.

Build docs developers (and LLMs) love