Files
sitomat/docker/nginx/templates/default.conf.template
T

62 lines
3.3 KiB
Plaintext
Raw Normal View History

2026-10-09 03:26:14 +07:00
# ─────────────────────────────────────────────────────────────────────────────
# sitomat — SINGLE-DOMAIN reverse proxy (Opsi A).
#
# ONE public origin serves BOTH the web UI and the API; routing is by PATH. A
# small, explicit set of API prefixes goes to the API, everything else to the
# web — which is what lets the deployment expose a single port / domain.
#
# WHY ONLY THESE PREFIXES: most API routes (`/datasets`, `/submissions`,
# `/services`, `/standards`, …) COLLIDE with web pages of the same name. They do
# not need a public path because the web calls them SERVER-SIDE (Eden →
# `http://api:13000`) over the internal network. Only endpoints the BROWSER — or
# an external M2M client — hits directly are routed here:
#
# /api/auth/* better-auth (login/session) ← NEXT_PUBLIC_API_URL
# /api/v1/* documented read API (F09-A)
# /public/* open-data downloads (F07)
# /ingest/v1/* push ingest (F09-B)
# /docs swagger
# /health health check
# /datasets/<id>/versions/<v>/download browser download (F02)
#
# The last one is a REGEX on purpose: it is the ONLY browser-facing API path at
# the ROOT, and a plain prefix would swallow the web's `/datasets/[id]` page.
#
# With web + API on ONE origin there is no cross-origin request, so CORS is moot
# and the session cookie stays host-only (no `SESSION_COOKIE_DOMAIN`).
#
# `${PUBLIC_HOST}` is substituted by the nginx image's envsubst step.
# This is HTTP; add `listen 443 ssl` + certificates when TLS terminates here.
# ─────────────────────────────────────────────────────────────────────────────
# Uploads (F02) can be several MB — nginx's 1m default would answer 413.
client_max_body_size 100m;
server {
listen 80;
server_name ${PUBLIC_HOST};
# Inherited by every `location` below.
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# better-auth checks the browser's Origin against WEB_URL; forward it as-is.
proxy_set_header Origin $http_origin;
# ── API ──────────────────────────────────────────────────────────────────
location = /health { proxy_pass http://api:13000; }
location /docs { proxy_pass http://api:13000; }
location /api/ { proxy_pass http://api:13000; }
location /public/ { proxy_pass http://api:13000; }
location /ingest/ { proxy_pass http://api:13000; }
# The one root-level browser API path (see the header note). Regex locations
# are evaluated BEFORE the prefix `location /` below, so this wins.
location ~ ^/datasets/[^/]+/versions/[^/]+/download$ {
proxy_pass http://api:13000;
}
# ── Web (everything else) ────────────────────────────────────────────────
location / { proxy_pass http://web:13001; }
}