Frontend: API_BASE env-driven (VITE_API_BASE, default localhost:8000 so dev is unchanged); vite.config.js base from FESTIVAL4D_BASE. Prod build 'FESTIVAL4D_BASE=/festifun/ VITE_API_BASE=/festifun' serves same-origin under the prefix. Validated end-to-end via a local proxy mirroring the nginx config: app boots, media Range 206, 3D + overlays + timeline render under /festifun. deploy/: nginx location blocks (prefix strip + Range), systemd unit (uvicorn 127.0.0.1:8000, no keys on the public box), DEPLOY.md. Labels baked into the shipped DB locally so detect can't spend credits from an anonymous public endpoint. Backend suite 103 passed; default build unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
47 lines
1.9 KiB
Plaintext
47 lines
1.9 KiB
Plaintext
# Festival 4D — nginx location block for hosting under digalot.fyi/festifun
|
|
#
|
|
# Drop these `location` blocks inside the existing `server { }` for digalot.fyi (the one that
|
|
# already terminates TLS for the domain). The app is served entirely under the /festifun prefix:
|
|
# /festifun/ -> static SPA build (frontend/dist)
|
|
# /festifun/api/... -> uvicorn backend on 127.0.0.1:8000 (prefix stripped)
|
|
# /festifun/media/... -> uvicorn backend (video files, Range-capable)
|
|
#
|
|
# Adjust FESTIFUN_ROOT to wherever you rsync the build (see deploy/DEPLOY.md).
|
|
|
|
# --- static SPA (built with FESTIVAL4D_BASE=/festifun/) ---
|
|
location /festifun/ {
|
|
alias /var/www/festifun/dist/;
|
|
try_files $uri $uri/ /festifun/index.html; # SPA fallback
|
|
}
|
|
|
|
# bare /festifun -> /festifun/
|
|
location = /festifun {
|
|
return 301 /festifun/;
|
|
}
|
|
|
|
# --- API: strip the /festifun prefix, proxy to uvicorn ---
|
|
# The trailing slash on proxy_pass performs the prefix strip:
|
|
# /festifun/api/manifest -> http://127.0.0.1:8000/api/manifest
|
|
location /festifun/api/ {
|
|
proxy_pass http://127.0.0.1:8000/api/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_read_timeout 300s; # POST /api/events/detect runs ffmpeg + (optional) an AI call
|
|
}
|
|
|
|
# --- media: video files, Range-capable (required for <video> seeking) ---
|
|
location /festifun/media/ {
|
|
proxy_pass http://127.0.0.1:8000/media/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header Range $http_range; # forward Range for seeking
|
|
proxy_set_header If-Range $http_if_range;
|
|
proxy_force_ranges on;
|
|
}
|
|
|
|
# Optional, faster alternative for /festifun/media/: serve the files directly instead of
|
|
# proxying (uvicorn StaticFiles already does Range, but nginx is faster for large media):
|
|
# location /festifun/media/ { alias /var/www/festifun/data/raw/; }
|