BetterFrame/deploy/angie/betterframe.conf

114 lines
4 KiB
Text
Raw Normal View History

# BetterFrame Angie/nginx config — routes admin, kiosk-api, ws, node-red.
#
# Place in /etc/angie/conf.d/betterframe.conf or /etc/nginx/conf.d/betterframe.conf
# Run on the Pi alongside the server. TLS termination here; backend services
# bind to 0.0.0.0 but firewall should restrict to localhost in production.
# Upstreams (BSB services)
upstream betterframe_admin { server 127.0.0.1:18080; keepalive 16; }
upstream betterframe_api { server 127.0.0.1:18081; keepalive 16; }
upstream betterframe_ws { server 127.0.0.1:18082; }
upstream betterframe_nodered { server 127.0.0.1:1880; keepalive 8; }
# Rate limiting for public endpoints
limit_req_zone $binary_remote_addr zone=bf_public:10m rate=30r/s;
server {
listen 80;
listen [::]:80;
server_name betterframe.local _;
# In production: redirect to HTTPS
# return 301 https://$host$request_uri;
# For now: serve plain HTTP
client_max_body_size 16M;
# ---- Admin UI + admin API (session-authenticated) ----
location /admin/ {
proxy_pass http://betterframe_admin;
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_http_version 1.1;
proxy_set_header Connection "";
}
location = /admin { return 301 /admin/; }
location /setup { proxy_pass http://betterframe_admin; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
location /auth/ { proxy_pass http://betterframe_admin; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
location /static/ { proxy_pass http://betterframe_admin; }
# ---- Kiosk REST API (Bearer kiosk-key) ----
location /api/kiosk/ {
proxy_pass http://betterframe_api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
location /api/pair/ {
# Rate-limit pairing initiate to deter brute force
limit_req zone=bf_public burst=10 nodelay;
proxy_pass http://betterframe_api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# ---- Admin API (session-authenticated) ----
location /api/admin/ {
proxy_pass http://betterframe_admin;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# ---- Live kiosk WebSocket channel ----
location /ws/kiosk {
proxy_pass http://betterframe_ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 86400s; # long-lived
proxy_send_timeout 86400s;
}
# ---- Node-RED dashboard (admin-only) ----
location /nrdp/ {
# auth_request /api/admin/_check; # enable when auth-check endpoint ready
rewrite ^/nrdp/(.*) /$1 break;
proxy_pass http://betterframe_nodered;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# ---- Node-RED HTTP-in (public, rate-limited) ----
location /in/public/ {
limit_req zone=bf_public burst=20 nodelay;
rewrite ^/in/public/(.*) /public/$1 break;
proxy_pass http://betterframe_nodered;
}
# ---- Node-RED HTTP-in (kiosk-gated) ----
location /in/kiosk/ {
# Bearer kiosk-key validated by Node-RED flow
rewrite ^/in/kiosk/(.*) /kiosk/$1 break;
proxy_pass http://betterframe_nodered;
}
# ---- Health/readiness/version (public) ----
location ~ ^/(healthz|readyz|version)$ {
proxy_pass http://betterframe_admin;
}
# ---- Root redirect ----
location = / {
proxy_pass http://betterframe_admin;
}
}