first commit
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# 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; }
|
||||
}
|
||||
Reference in New Issue
Block a user