# Full androidcast vhost for Alpine BE — listen 80 only. # FE (apps.f0xx.org / s.f0xx.org / notify.f0xx.org) proxies here: cast01–03 cluster :80 # Port 8089 is a different service (e.g. Janus) — not this vhost. map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80 default_server; listen [::]:80 default_server; # FE proxies https://apps.f0xx.org/ here as GET / — hub lives under /app/androidcast_project/ location = / { return 301 https://$http_host/app/androidcast_project/; } # OTA v0 static tree — devices fetch https://apps.f0xx.org/v0/ota/channel/stable.json location ^~ /v0/ota/ { alias /var/www/localhost/htdocs/apps/app/androidcast_project/ota-artifacts/v0/ota/; add_header Cache-Control "public, max-age=60"; } # Favicon — served from hub root (shared by all sub-apps via explicit tags) location = /favicon.ico { alias /var/www/localhost/htdocs/apps/app/androidcast_project/favicon.ico; access_log off; expires 7d; } location = /apple-touch-icon.ico { alias /var/www/localhost/htdocs/apps/app/androidcast_project/apple-touch-icon.ico; access_log off; expires 7d; } location = /app/androidcast_project { return 301 /app/androidcast_project/; } location = /app/androidcast_project/index.php { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/localhost/htdocs/apps/app/androidcast_project/index.php; fastcgi_param SCRIPT_NAME /app/androidcast_project/index.php; } location = /app/androidcast_project/ { rewrite ^ /app/androidcast_project/index.php last; } # Shared session auth at project root — composed ac/* backend # Includes 2FA cross-device and polling endpoints location ~ ^/app/androidcast_project/(login|logout|register|two-factor(?:/approve)?|verify-email|api/two-factor(?:/poll)?)(/|$) { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/ac/composed/backend/public/index.php; fastcgi_param SCRIPT_NAME /app/androidcast_project/issues/index.php; fastcgi_param REQUEST_URI $request_uri; client_max_body_size 4m; } location /app/androidcast_project/ { alias /var/www/localhost/htdocs/apps/app/androidcast_project/; index index.php index.html; try_files $uri $uri/ =404; } location = /app/androidcast_project/graphs { return 301 /app/androidcast_project/graphs/; } # --- /issues/ served from composed ac/* backend --- location = /app/androidcast_project/issues { return 301 /app/androidcast_project/issues/; } location ^~ /app/androidcast_project/issues/assets/ { alias /var/www/ac/composed/backend/public/assets/; } location = /app/androidcast_project/issues/api/upload.php { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/ac/composed/backend/public/api/upload.php; fastcgi_param SCRIPT_NAME /app/androidcast_project/issues/api/upload.php; fastcgi_param REQUEST_URI $request_uri; client_max_body_size 4m; } location ^~ /app/androidcast_project/issues/ { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/ac/composed/backend/public/index.php; fastcgi_param SCRIPT_NAME /app/androidcast_project/issues/index.php; fastcgi_param REQUEST_URI $request_uri; client_max_body_size 4m; } # Legacy /crashes/ → 301 to /issues/ (SPEC §7) location = /app/androidcast_project/crashes { return 301 /app/androidcast_project/issues/; } location ^~ /app/androidcast_project/crashes/ { rewrite ^/app/androidcast_project/crashes/?(.*)$ /app/androidcast_project/issues/$1 permanent; } location ^~ /app/androidcast_project/crashes/assets/ { alias /var/www/ac/composed/backend/public/assets/; } location = /app/androidcast_project/crashes/api/upload.php { return 301 /app/androidcast_project/issues/api/upload.php; } location ^~ /app/androidcast_project/graphs/assets/ { alias /var/www/ac/composed/backend/public/assets/; } location = /app/androidcast_project/graphs/api/graphs.php { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/ac/composed/backend/public/api/graphs.php; fastcgi_param SCRIPT_NAME /app/androidcast_project/graphs/api/graphs.php; fastcgi_param REQUEST_URI $request_uri; } location = /app/androidcast_project/graphs/api/graph_upload.php { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/ac/composed/backend/public/api/graph_upload.php; fastcgi_param SCRIPT_NAME /app/androidcast_project/graphs/api/graph_upload.php; fastcgi_param REQUEST_URI $request_uri; client_max_body_size 4m; } location ^~ /app/androidcast_project/graphs/ { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/ac/composed/backend/public/index.php; fastcgi_param SCRIPT_NAME /app/androidcast_project/graphs/index.php; fastcgi_param REQUEST_URI $request_uri; client_max_body_size 4m; } location = /app/androidcast_project/build { return 301 /app/androidcast_project/build/; } location ^~ /app/androidcast_project/build/assets/ { alias /var/www/ac/workspace/ac-be-builder/public/assets/; } location ^~ /app/androidcast_project/build/ { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/ac/workspace/ac-be-builder/public/index.php; fastcgi_param SCRIPT_NAME /app/androidcast_project/build/index.php; fastcgi_param REQUEST_URI $request_uri; client_max_body_size 512m; fastcgi_read_timeout 1800s; } # ── grafana-auth-check: internal auth_request endpoint ─────────────────── location = /app/androidcast_project/api/grafana-auth-check.php { internal; include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/ac/composed/backend/public/api/grafana-auth-check.php; fastcgi_param SCRIPT_NAME /app/androidcast_project/api/grafana-auth-check.php; fastcgi_param REQUEST_URI $request_uri; fastcgi_param HTTP_COOKIE $http_cookie; } location @monitor_login_redirect { return 302 /app/androidcast_project/login?redirect=$request_uri; } # ── Grafana at cast04:3000 ──────────────────────────────────────────────── location = /app/androidcast_project/monitor { return 301 /app/androidcast_project/monitor/; } location /app/androidcast_project/monitor/ { auth_request /app/androidcast_project/api/grafana-auth-check.php; auth_request_set $grafana_user $upstream_http_x_webauth_user; error_page 401 = @monitor_login_redirect; proxy_pass http://10.7.16.239:3000/; proxy_set_header Host $http_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_set_header X-WEBAUTH-USER $grafana_user; proxy_http_version 1.1; proxy_read_timeout 300; proxy_send_timeout 300; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } # ── Alertmanager at cast04:9093 ─────────────────────────────────────────── location = /app/androidcast_project/alertmanager { return 301 /app/androidcast_project/alertmanager/; } location /app/androidcast_project/alertmanager/ { auth_request /app/androidcast_project/api/grafana-auth-check.php; auth_request_set $grafana_user $upstream_http_x_webauth_user; error_page 401 = @monitor_login_redirect; proxy_pass http://10.7.16.239:9093/; proxy_set_header Host $http_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_http_version 1.1; proxy_read_timeout 120; proxy_send_timeout 120; } # ── Broadcast admin dashboard (/app/androidcast_project/broadcast/) ─────── location = /app/androidcast_project/broadcast { return 301 /app/androidcast_project/broadcast/; } location /app/androidcast_project/broadcast/ { auth_request /app/androidcast_project/api/grafana-auth-check.php; auth_request_set $auth_user $upstream_http_x_webauth_user; error_page 401 = @monitor_login_redirect; include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/ac/broadcast/public/index.php; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param HTTP_COOKIE $http_cookie; fastcgi_param HTTP_AUTHORIZATION $http_authorization; } # --- Gitea web UI (lab browse; mirrors configured separately) --- location = /app/androidcast_project/git { return 301 /app/androidcast_project/git/; } location ^~ /app/androidcast_project/git/ { proxy_pass http://127.0.0.1:3000/; proxy_http_version 1.1; 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_set_header X-Forwarded-Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_read_timeout 1800s; proxy_send_timeout 1800s; client_max_body_size 512m; } # ── SFU signaling — Janus Gateway WebRTC backend ───────────────────────── # REST API → PHP signaling service location /app/androidcast_project/sfu/api/ { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/ac/workspace/ac-ms-sfu-signaling/public/index.php; fastcgi_param SCRIPT_NAME /app/androidcast_project/sfu/index.php; fastcgi_param REQUEST_URI $request_uri; fastcgi_param HTTP_COOKIE $http_cookie; fastcgi_param HTTP_AUTHORIZATION $http_authorization; } # WebSocket → Janus on cast02 location /app/androidcast_project/sfu/ws { proxy_pass http://10.7.16.237:8188/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; proxy_read_timeout 3600s; } # Catch-all SFU paths → PHP signaling front controller location = /app/androidcast_project/sfu { return 301 /app/androidcast_project/sfu/; } location ^~ /app/androidcast_project/sfu/ { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/ac/workspace/ac-ms-sfu-signaling/public/index.php; fastcgi_param SCRIPT_NAME /app/androidcast_project/sfu/index.php; fastcgi_param REQUEST_URI $request_uri; fastcgi_param HTTP_COOKIE $http_cookie; fastcgi_param HTTP_AUTHORIZATION $http_authorization; } location ~ \.php$ { include /etc/nginx/fastcgi.conf; fastcgi_pass 127.0.0.1:9000; } } # ── notify.f0xx.org — Broadcast public landing pages ───────────────────────── # CNAME: notify.f0xx.org → apps.f0xx.org → cluster (cast01–03) server { listen 80; listen [::]:80; server_name notify.f0xx.org; root /var/www/ac/broadcast/public; index index.php; location = /favicon.ico { alias /var/www/localhost/htdocs/apps/app/androidcast_project/favicon.ico; access_log off; expires 7d; } location / { try_files $uri /index.php?$query_string; } location ~ \.php$ { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/ac/broadcast/public/index.php; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param HTTP_COOKIE $http_cookie; fastcgi_param HTTP_AUTHORIZATION $http_authorization; } location ~* \.(js|css|png|jpg|ico|woff2?)$ { expires 7d; add_header Cache-Control "public"; } }