Reverse Proxy

Reverse Proxy

WeWorks runs as multiple services (landing, client, API, docs). In production you typically terminate HTTPS at nginx, Caddy, or Traefik and route by subdomain.

SubdomainServiceInternal port
weworks.com.au or wwwLanding3000
client.weworks.com.auClient app3001
api.weworks.com.auAPI5003
docs.weworks.com.auDocumentation3002

Example flow:

https://client.example.com  →  nginx  →  localhost:3001  (client)
https://api.example.com     →  nginx  →  localhost:5003  (api)

The client proxies browser requests to /api/v1/*. In production, set:

  • Client: NEXT_PUBLIC_API_URL=https://api.example.com
  • API: FRONTEND_URL=https://client.example.com

nginx example — client

server {
    listen 443 ssl http2;
    server_name client.example.com;
 
    # ssl_certificate /etc/letsencrypt/live/client.example.com/fullchain.pem;
    # ssl_certificate_key /etc/letsencrypt/live/client.example.com/privkey.pem;
 
    location / {
        proxy_pass http://127.0.0.1:3001;
        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_read_timeout 5m;
    }
 
    client_max_body_size 20M;
}

nginx example — API

server {
    listen 443 ssl http2;
    server_name api.example.com;
 
    location / {
        proxy_pass http://127.0.0.1:5003;
        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_read_timeout 5m;
    }
 
    client_max_body_size 20M;
}

nginx example — landing

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
 
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

HTTPS

Use Certbot with the nginx plugin:

sudo certbot --nginx -d client.example.com -d api.example.com

The API should be served over HTTPS in production — some auth flows expect secure origins.

Docker Compose note

When using root docker-compose.yml, containers expose ports on the host (3001, 5003, etc.). Point nginx at 127.0.0.1 on those ports, or attach nginx to the same Docker network and use service names (weworks_client:3001, weworks_api:5003).

Firewall

Allow HTTP/HTTPS only:

sudo ufw allow 'Nginx Full'

Do not expose PostgreSQL (5432) publicly.