1 08-Reverse-Proxy
faycel edited this page 2026-02-26 20:30:45 +00:00

08 — Nginx Reverse Proxy

This page documents the Nginx reverse proxy configuration used in production.

Snapshot date: 2026-02
Stack: infra
Mode: Docker Swarm


1. Purpose

Nginx is responsible for:

  • TLS termination
  • Routing traffic to internal services
  • Exposing only required ports
  • Acting as single public entry point

Only Nginx is exposed on ports:

  • 80 (HTTP)
  • 443 (HTTPS)

All other services remain internal.


2. Network Design

Nginx is attached to:

  • web (public overlay network)
  • internal (private overlay network)

Applications (Forgejo, Mattermost) are attached to:

  • internal
  • optionally web if required

This allows:

  • Public traffic → Nginx
  • Nginx → internal services
  • No direct external exposure of apps

3. Swarm Service

Verify Nginx service:

sudo docker service ls | grep nginx

Inspect service:

sudo docker service inspect infra_nginx

Expected:

  • Replicas: 1/1
  • Ports: 80, 443
  • Networks: web + internal

4. Port Exposure

Verify listening ports:

sudo ss -tulpn | grep -E '80|443'

Expected:

  • 0.0.0.0:80
  • 0.0.0.0:443

No other service should expose ports directly.


5. Reverse Proxy Example

Typical configuration inside Nginx:

server {
    listen 80;
    server_name code.example.com;

    location / {
        proxy_pass http://apps_forgejo:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Swarm DNS allows resolution by service name:

apps_forgejo
apps_mattermost

6. Why Infra Is Deployed Last

Deployment order:

  1. data
  2. apps
  3. infra

Reason:

If Nginx starts before application services exist, upstream DNS resolution may fail.

Deploying infra last ensures stable routing.


7. Security Notes

  • Only Nginx exposes public ports.
  • Applications must not expose ports directly.
  • TLS certificates are mounted via Certbot volume.
  • HTTP should redirect to HTTPS.

8. Reloading Nginx

If configuration changes:

sudo docker service update --force infra_nginx

This triggers rolling restart.