diff --git a/.gitignore b/.gitignore index f89afe65..d73a50c9 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,9 @@ node_modules/ # Media files (managed by Docker volumes, not git) /media/ +# Nginx generated configs (built from *.template at container startup) +nginx/conf.d/*.conf + # Ansible per-instance override (generated by Bunker Ops) docker-compose.override.yml diff --git a/nginx/conf.d/admin.conf b/nginx/conf.d/admin.conf deleted file mode 100644 index 46c09eb3..00000000 --- a/nginx/conf.d/admin.conf +++ /dev/null @@ -1,26 +0,0 @@ -server { - listen 80; - server_name admin.cmlite.org; - add_header X-Frame-Options "SAMEORIGIN" always; - - location / { - set $upstream_admin http://changemaker-v2-admin:3000; - proxy_pass $upstream_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_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # API proxy for admin SPA - location /api/ { - set $upstream_api http://changemaker-v2-api:4000; - proxy_pass $upstream_api; - 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; - } -} diff --git a/nginx/conf.d/api.conf b/nginx/conf.d/api.conf deleted file mode 100644 index 360fc6c0..00000000 --- a/nginx/conf.d/api.conf +++ /dev/null @@ -1,37 +0,0 @@ -server { - listen 80; - server_name api.cmlite.org api.betteredmonton.org api.pridecorner.ca; - add_header X-Frame-Options "SAMEORIGIN" always; - - # Media API endpoints (must come BEFORE / for longest prefix match) - location /media/ { - set $upstream_media http://changemaker-media-api:4100/api/; - proxy_pass $upstream_media; - 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; - - # Large upload support - client_max_body_size 10G; - proxy_read_timeout 3600s; - proxy_connect_timeout 75s; - proxy_request_buffering off; - - # WebSocket support - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # Main API (Express) - location / { - set $upstream_api http://changemaker-v2-api:4000; - proxy_pass $upstream_api; - 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_read_timeout 300s; - proxy_connect_timeout 75s; - } -} diff --git a/nginx/conf.d/api.conf.template b/nginx/conf.d/api.conf.template index 0415fe2e..7a6ced18 100644 --- a/nginx/conf.d/api.conf.template +++ b/nginx/conf.d/api.conf.template @@ -4,10 +4,10 @@ server { add_header X-Frame-Options "SAMEORIGIN" always; # Media API endpoints (must come BEFORE / for longest prefix match) - # Rewrites /media/* to /api/* on media-api (port 4100) + # Uses variable proxy_pass for runtime DNS resolution after container restarts location /media/ { - rewrite ^/media/(.*) /api/$1 break; - proxy_pass http://changemaker-media-api:4100; + set $upstream_media http://changemaker-media-api:4100/api/; + proxy_pass $upstream_media; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/nginx/conf.d/default.conf b/nginx/conf.d/default.conf deleted file mode 100644 index 276d6a72..00000000 --- a/nginx/conf.d/default.conf +++ /dev/null @@ -1,122 +0,0 @@ -# Default server — local development fallback -# Routes by path when not using subdomain-based routing -server { - listen 80 default_server; - server_name localhost _; - add_header X-Frame-Options "SAMEORIGIN" always; - - # Social media bot detection for OG meta tags - set $is_bot 0; - if ($http_user_agent ~* "(Twitterbot|facebookexternalhit|LinkedInBot|Slackbot|TelegramBot|WhatsApp|Discordbot|Googlebot|bingbot|Pinterest)") { - set $is_bot 1; - } - - # Bot-specific rewrites for rich social previews - location ~ ^/campaign/([^/]+)$ { - if ($is_bot) { - rewrite ^/campaign/(.+)$ /api/og/campaign/$1 last; - } - set $upstream_admin http://changemaker-v2-admin:3000; - proxy_pass $upstream_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_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - location ~ ^/p/([^/]+)$ { - if ($is_bot) { - rewrite ^/p/(.+)$ /api/og/page/$1 last; - } - set $upstream_admin http://changemaker-v2-admin:3000; - proxy_pass $upstream_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_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - location ~ ^/gallery/watch/([^/]+)$ { - if ($is_bot) { - rewrite ^/gallery/watch/(.+)$ /api/og/gallery/$1 last; - } - set $upstream_admin http://changemaker-v2-admin:3000; - proxy_pass $upstream_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_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # Admin GUI (default) - location / { - set $upstream_admin http://changemaker-v2-admin:3000; - proxy_pass $upstream_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_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # Media API admin routes (must come BEFORE /api/ for longest prefix match) - # Rewrites /api/media/* to /api/* on media-api - location /api/media/ { - rewrite ^/api/media/(.*) /api/$1 break; - proxy_pass http://changemaker-media-api:4100; - 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; - - # Large upload support - client_max_body_size 10G; - proxy_read_timeout 3600s; - proxy_connect_timeout 75s; - proxy_request_buffering off; - - # WebSocket support for future features - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # Media API routes rewrite (matches Vite dev proxy behavior) - # Rewrites /media/* to /api/* on media-api (port 4100) - # Uses variable proxy_pass for runtime DNS resolution after container restarts - location /media/ { - rewrite ^/media/(.*) /api/$1 break; - set $upstream_media_default http://changemaker-media-api:4100; - proxy_pass $upstream_media_default; - 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; - - # Large upload support - client_max_body_size 10G; - proxy_read_timeout 3600s; - proxy_connect_timeout 75s; - proxy_request_buffering off; - - # WebSocket support - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # API (Express) - location /api/ { - set $upstream_api http://changemaker-v2-api:4000; - proxy_pass $upstream_api; - 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; - } -} diff --git a/nginx/conf.d/default.conf.template b/nginx/conf.d/default.conf.template index 2371e9f3..ce94d632 100644 --- a/nginx/conf.d/default.conf.template +++ b/nginx/conf.d/default.conf.template @@ -7,7 +7,7 @@ server { # Social media bot detection for OG meta tags set $is_bot 0; - if ($http_user_agent ~* "(Twitterbot|facebookexternalhit|LinkedInBot|Slackbot|TelegramBot|WhatsApp|Discordbot|Googlebot|bingbot|Pinterest)") { + if ($http_user_agent ~* "(Twitterbot|facebookexternalhit|LinkedInBot|Slackbot|TelegramBot|WhatsApp|Discordbot|Googlebot|bingbot|Pinterest|Embedly|Quora Link Preview|Showyoubot|outbrain|vkShare|W3C_Validator)") { set $is_bot 1; } @@ -66,11 +66,13 @@ server { proxy_set_header Connection "upgrade"; } - # Media API routes rewrite (matches Vite dev proxy behavior) - # Rewrites /media/* to /api/* on media-api (port 4100) + # Media API (direct path - used by admin GUI media-api.ts client) + # Rewrites /media/* to /api/* (matches Vite dev proxy behavior) + # Uses variable proxy_pass for runtime DNS resolution after container restarts location /media/ { rewrite ^/media/(.*) /api/$1 break; - proxy_pass http://changemaker-media-api:4100; + set $upstream_media_default http://changemaker-media-api:4100; + proxy_pass $upstream_media_default; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/nginx/conf.d/public.conf b/nginx/conf.d/public.conf deleted file mode 100644 index 6686dbd5..00000000 --- a/nginx/conf.d/public.conf +++ /dev/null @@ -1,43 +0,0 @@ -server { - listen 80; - server_name map.cmlite.org; - add_header X-Frame-Options "SAMEORIGIN" always; - - root /usr/share/nginx/public-web/map; - index index.html; - - location / { - try_files $uri $uri/ /index.html; - } - - location /api/ { - set $upstream_api http://changemaker-v2-api:4000; - proxy_pass $upstream_api; - 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; - } -} - -server { - listen 80; - server_name influence.cmlite.org; - add_header X-Frame-Options "SAMEORIGIN" always; - - root /usr/share/nginx/public-web/influence; - index index.html; - - location / { - try_files $uri $uri/ /index.html; - } - - location /api/ { - set $upstream_api http://changemaker-v2-api:4000; - proxy_pass $upstream_api; - 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; - } -} diff --git a/nginx/conf.d/services.conf b/nginx/conf.d/services.conf deleted file mode 100644 index 9f1959f8..00000000 --- a/nginx/conf.d/services.conf +++ /dev/null @@ -1,716 +0,0 @@ -# Gitea — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name git.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org" always; - - # Increase max body size for large git pushes (2GB) - client_max_body_size 2048M; - - location / { - set $upstream_gitea http://gitea-changemaker:3000; - proxy_pass $upstream_gitea; - proxy_hide_header X-Frame-Options; - 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; - } -} - -# n8n — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name n8n.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org" always; - - location / { - set $upstream_n8n http://n8n-changemaker:5678; - proxy_pass $upstream_n8n; - proxy_hide_header X-Frame-Options; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -# Grafana — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name grafana.cmlite.org grafana.betteredmonton.org grafana.pridecorner.ca; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org app.betteredmonton.org" always; - - location / { - set $upstream_grafana http://grafana-changemaker:3000; - proxy_pass $upstream_grafana; - proxy_hide_header X-Frame-Options; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -# NocoDB (data browser) — allows iframe embedding from admin -server { - listen 80; - server_name db.cmlite.org db.betteredmonton.org db.pridecorner.ca; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org app.betteredmonton.org" always; - - location / { - set $upstream_nocodb http://changemaker-v2-nocodb:8080; - proxy_pass $upstream_nocodb; - proxy_hide_header X-Frame-Options; - 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; - } -} - -# Listmonk -server { - listen 80; - server_name listmonk.cmlite.org listmonk.betteredmonton.org listmonk.pridecorner.ca; - add_header X-Frame-Options "SAMEORIGIN" always; - - location / { - set $upstream_listmonk http://listmonk-app:9000; - proxy_pass $upstream_listmonk; - 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; - } -} - -# MkDocs — allows iframe embedding from admin -server { - listen 80; - server_name docs.cmlite.org docs.betteredmonton.org docs.pridecorner.ca; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org app.betteredmonton.org" always; - - location / { - set $upstream_mkdocs http://mkdocs-changemaker:8000; - proxy_pass $upstream_mkdocs; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -# Code Server — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name code.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org" always; - - location / { - set $upstream_code http://code-server-changemaker:8080; - proxy_pass $upstream_code; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -# MailHog (email testing) — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name mail.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org" always; - - location / { - set $upstream_mailhog http://mailhog-changemaker:8025; - proxy_pass $upstream_mailhog; - proxy_hide_header X-Frame-Options; - 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; - # WebSocket support for MailHog live updates - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -# Mini QR — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name qr.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org" always; - - location / { - set $upstream_miniqr http://mini-qr:8080; - proxy_pass $upstream_miniqr; - proxy_hide_header X-Frame-Options; - 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; - } -} - -# Excalidraw — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name draw.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org" always; - - location / { - set $upstream_excalidraw http://excalidraw-changemaker:80; - proxy_pass $upstream_excalidraw; - proxy_hide_header X-Frame-Options; - 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; - - # WebSocket support for collaboration - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - } -} - -# Vaultwarden (password manager) — allows iframe embedding from admin -server { - listen 80; - server_name vault.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org" always; - - location / { - set $upstream_vaultwarden http://vaultwarden-changemaker:80; - proxy_pass $upstream_vaultwarden; - proxy_hide_header X-Frame-Options; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - } -} - -# Rocket.Chat (team chat) — allows iframe embedding from admin -server { - listen 80; - server_name chat.cmlite.org chat.betteredmonton.org chat.pridecorner.ca; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org app.betteredmonton.org" always; - - location / { - set $upstream_rocketchat http://rocketchat-changemaker:3000; - proxy_pass $upstream_rocketchat; - proxy_hide_header X-Frame-Options; - 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; - # WebSocket support (critical for RC real-time messaging) - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - client_max_body_size 100m; - } -} - -# Gancio (event management) — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name events.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org" always; - - location / { - set $upstream_gancio http://gancio-changemaker:13120; - proxy_pass $upstream_gancio; - proxy_hide_header X-Frame-Options; - 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; - } -} - -# Jitsi Meet (video conferencing) — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name meet.cmlite.org meet.betteredmonton.org meet.pridecorner.ca; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org app.betteredmonton.org" always; - - location / { - set $upstream_jitsi http://jitsi-web-changemaker:80; - proxy_pass $upstream_jitsi; - proxy_hide_header X-Frame-Options; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - } -} - -# --- Embed proxy ports (for iframe embedding without DNS/subdomain) --- -# These listen on dedicated ports so the admin GUI can iframe services via -# localhost:PORT, bypassing X-Frame-Options without needing *.localhost DNS. - -server { - listen 8881; - location / { - set $upstream_nocodb http://changemaker-v2-nocodb:8080; - proxy_pass $upstream_nocodb; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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; - } -} - -server { - listen 8882; - location / { - set $upstream_n8n http://n8n-changemaker:5678; - proxy_pass $upstream_n8n; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -server { - listen 8883; - # Increase max body size for large git pushes (2GB) - client_max_body_size 2048M; - location / { - set $upstream_gitea http://gitea-changemaker:3000; - proxy_pass $upstream_gitea; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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; - } -} - -server { - listen 8884; - location / { - set $upstream_mailhog http://mailhog-changemaker:8025; - proxy_pass $upstream_mailhog; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -server { - listen 8885; - location / { - set $upstream_miniqr http://mini-qr:8080; - proxy_pass $upstream_miniqr; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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; - } -} - -# Excalidraw embed proxy (port 8886) -server { - listen 8886; - location / { - set $upstream_excalidraw http://excalidraw-changemaker:80; - proxy_pass $upstream_excalidraw; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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; - - # WebSocket support for collaboration - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - } -} - -# Admin GUI — app subdomain -server { - listen 80; - server_name app.cmlite.org app.betteredmonton.org app.pridecorner.ca; - add_header X-Frame-Options "SAMEORIGIN" always; - - # Social media bot detection for OG meta tags - set $is_bot 0; - if ($http_user_agent ~* "(Twitterbot|facebookexternalhit|LinkedInBot|Slackbot|TelegramBot|WhatsApp|Discordbot|Googlebot|bingbot|Pinterest|Embedly|Quora Link Preview|Showyoubot|outbrain|vkShare|W3C_Validator)") { - set $is_bot 1; - } - - # Bot-specific rewrites — serve OG meta from API for rich social previews - location ~ ^/campaign/([^/]+)$ { - if ($is_bot) { - rewrite ^/campaign/(.+)$ /api/og/campaign/$1 last; - } - set $upstream_admin http://changemaker-v2-admin:3000; - proxy_pass $upstream_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_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - location ~ ^/p/([^/]+)$ { - if ($is_bot) { - rewrite ^/p/(.+)$ /api/og/page/$1 last; - } - set $upstream_admin http://changemaker-v2-admin:3000; - proxy_pass $upstream_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_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - location ~ ^/gallery/watch/([^/]+)$ { - if ($is_bot) { - rewrite ^/gallery/watch/(.+)$ /api/og/gallery/$1 last; - } - set $upstream_admin http://changemaker-v2-admin:3000; - proxy_pass $upstream_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_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - location / { - set $upstream_admin http://changemaker-v2-admin:3000; - proxy_pass $upstream_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; - # WebSocket support for Vite HMR - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # Media API (direct path - used by admin GUI media-api.ts client) - # Rewrites /media/* to /api/* (matches Vite dev proxy behavior) - # Uses variable proxy_pass for runtime DNS resolution after container restarts - location /media/ { - rewrite ^/media/(.*) /api/$1 break; - set $upstream_media_app http://changemaker-media-api:4100; - proxy_pass $upstream_media_app; - 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; - - # Large file upload support - client_max_body_size 10G; - proxy_read_timeout 3600s; - proxy_connect_timeout 75s; - proxy_request_buffering off; - - # WebSocket support - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # Media API endpoints (must come BEFORE /api/ for longest prefix match) - location /api/media/ { - set $upstream_media http://changemaker-media-api:4100; - proxy_pass $upstream_media; - 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; - - # Large upload support - client_max_body_size 10G; - proxy_read_timeout 3600s; - proxy_connect_timeout 75s; - proxy_request_buffering off; - - # WebSocket support - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # MkDocs proxy (docs search index for volunteer map) - location /mkdocs-proxy/ { - set $upstream_mkdocs http://mkdocs-changemaker:8000; - rewrite ^/mkdocs-proxy/(.*) /$1 break; - proxy_pass $upstream_mkdocs; - 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; - } - - # API (Express) - location /api/ { - set $upstream_api http://changemaker-v2-api:4000; - proxy_pass $upstream_api; - 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; - } -} - -# MkDocs built static site — root domain -server { - listen 80; - server_name cmlite.org; - - location / { - set $upstream_site http://mkdocs-site-server-changemaker:80; - proxy_pass $upstream_site; - 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; - } -} - -# Root domain — routes to admin GUI (supports custom DOMAIN env var) -server { - listen 80; - server_name betteredmonton.org pridecorner.ca; - add_header X-Frame-Options "SAMEORIGIN" always; - - location / { - set $upstream_admin http://changemaker-v2-admin:3000; - proxy_pass $upstream_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; - # WebSocket support for Vite HMR - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # Media API (direct path - used by admin GUI media-api.ts client) - # Uses variable proxy_pass for runtime DNS resolution after container restarts - location /media/ { - rewrite ^/media/(.*) /api/$1 break; - set $upstream_media_root http://changemaker-media-api:4100; - proxy_pass $upstream_media_root; - 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; - - # Large file upload support - client_max_body_size 10G; - proxy_read_timeout 3600s; - proxy_connect_timeout 75s; - proxy_request_buffering off; - - # WebSocket support - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # Media API endpoints (must come BEFORE /api/ for longest prefix match) - location /api/media/ { - set $upstream_media http://changemaker-media-api:4100; - proxy_pass $upstream_media; - 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; - - # Large upload support - client_max_body_size 10G; - proxy_read_timeout 3600s; - proxy_connect_timeout 75s; - proxy_request_buffering off; - - # WebSocket support - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # API (Express) - location /api/ { - set $upstream_api http://changemaker-v2-api:4000; - proxy_pass $upstream_api; - 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; - } -} - -# Homepage dashboard — allows iframe embedding from admin -server { - listen 80; - server_name home.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org app.betteredmonton.org" always; - - location / { - set $upstream_homepage http://homepage-changemaker:3000; - proxy_pass $upstream_homepage; - proxy_hide_header X-Frame-Options; - 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; - } -} - -# Homepage embed proxy (port 8887) -server { - listen 8887; - location / { - set $upstream_homepage http://homepage-changemaker:3000; - proxy_pass $upstream_homepage; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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; - } -} - -# Vaultwarden embed proxy (port 8890) -server { - listen 8890; - location / { - set $upstream_vaultwarden http://vaultwarden-changemaker:80; - proxy_pass $upstream_vaultwarden; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - } -} - -# Rocket.Chat embed proxy (port 8891) -server { - listen 8891; - location / { - set $upstream_rocketchat http://rocketchat-changemaker:3000; - proxy_pass $upstream_rocketchat; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - client_max_body_size 100m; - } -} - -# Gancio embed proxy (port 8892) -server { - listen 8892; - location / { - set $upstream_gancio http://gancio-changemaker:13120; - proxy_pass $upstream_gancio; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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; - } -} - -# Jitsi Meet embed proxy (port 8893) -server { - listen 8893; - location / { - set $upstream_jitsi http://jitsi-web-changemaker:80; - proxy_pass $upstream_jitsi; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - } -} - -# Grafana embed proxy (port 8894) -server { - listen 8894; - location / { - set $upstream_grafana http://grafana-changemaker:3000; - proxy_pass $upstream_grafana; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -# Alertmanager embed proxy (port 8895) -server { - listen 8895; - location / { - set $upstream_alertmanager http://alertmanager-changemaker:9093; - proxy_pass $upstream_alertmanager; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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; - } -} diff --git a/nginx/conf.d/services.conf.template b/nginx/conf.d/services.conf.template index 72784d08..19ebdcd3 100644 --- a/nginx/conf.d/services.conf.template +++ b/nginx/conf.d/services.conf.template @@ -371,7 +371,7 @@ server { # Social media bot detection for OG meta tags set $is_bot 0; - if ($http_user_agent ~* "(Twitterbot|facebookexternalhit|LinkedInBot|Slackbot|TelegramBot|WhatsApp|Discordbot|Googlebot|bingbot|Pinterest)") { + if ($http_user_agent ~* "(Twitterbot|facebookexternalhit|LinkedInBot|Slackbot|TelegramBot|WhatsApp|Discordbot|Googlebot|bingbot|Pinterest|Embedly|Quora Link Preview|Showyoubot|outbrain|vkShare|W3C_Validator)") { set $is_bot 1; } @@ -430,11 +430,13 @@ server { proxy_set_header Connection "upgrade"; } - # Media API routes rewrite (matches Vite dev proxy behavior) - # Rewrites /media/* to /api/* on media-api (port 4100) + # Media API (direct path - used by admin GUI media-api.ts client) + # Rewrites /media/* to /api/* (matches Vite dev proxy behavior) + # Uses variable proxy_pass for runtime DNS resolution after container restarts location /media/ { rewrite ^/media/(.*) /api/$1 break; - proxy_pass http://changemaker-media-api:4100; + set $upstream_media_app http://changemaker-media-api:4100; + proxy_pass $upstream_media_app; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -471,6 +473,17 @@ server { proxy_set_header Connection "upgrade"; } + # MkDocs proxy (docs search index for volunteer map) + location /mkdocs-proxy/ { + set $upstream_mkdocs http://mkdocs-changemaker:8000; + rewrite ^/mkdocs-proxy/(.*) /$1 break; + proxy_pass $upstream_mkdocs; + 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; + } + # API (Express) location /api/ { set $upstream_api http://changemaker-v2-api:4000; diff --git a/nginx/conf.d/services.conf.template.bak b/nginx/conf.d/services.conf.template.bak deleted file mode 100644 index cdb32193..00000000 --- a/nginx/conf.d/services.conf.template.bak +++ /dev/null @@ -1,413 +0,0 @@ -# Gitea — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name git.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org" always; - - # Increase max body size for large git pushes (2GB) - client_max_body_size 2048M; - - location / { - set $upstream_gitea http://gitea-changemaker:3000; - proxy_pass $upstream_gitea; - proxy_hide_header X-Frame-Options; - 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; - } -} - -# n8n — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name n8n.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org" always; - - location / { - set $upstream_n8n http://n8n-changemaker:5678; - proxy_pass $upstream_n8n; - proxy_hide_header X-Frame-Options; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -# Grafana -server { - listen 80; - server_name grafana.cmlite.org grafana.betteredmonton.org; - add_header X-Frame-Options "SAMEORIGIN" always; - - location / { - set $upstream_grafana http://grafana-changemaker:3000; - proxy_pass $upstream_grafana; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -# NocoDB (data browser) — allows iframe embedding from admin -server { - listen 80; - server_name db.cmlite.org db.betteredmonton.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org app.betteredmonton.org" always; - - location / { - set $upstream_nocodb http://changemaker-v2-nocodb:8080; - proxy_pass $upstream_nocodb; - proxy_hide_header X-Frame-Options; - 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; - } -} - -# Listmonk -server { - listen 80; - server_name listmonk.cmlite.org listmonk.betteredmonton.org; - add_header X-Frame-Options "SAMEORIGIN" always; - - location / { - set $upstream_listmonk http://listmonk-app:9000; - proxy_pass $upstream_listmonk; - 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; - } -} - -# MkDocs — allows iframe embedding from admin -server { - listen 80; - server_name docs.cmlite.org docs.betteredmonton.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org app.betteredmonton.org" always; - - location / { - set $upstream_mkdocs http://mkdocs-changemaker:8000; - proxy_pass $upstream_mkdocs; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -# Code Server — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name code.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org" always; - - location / { - set $upstream_code http://code-server-changemaker:8080; - proxy_pass $upstream_code; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -# MailHog (email testing) — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name mail.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org" always; - - location / { - set $upstream_mailhog http://mailhog-changemaker:8025; - proxy_pass $upstream_mailhog; - proxy_hide_header X-Frame-Options; - 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; - # WebSocket support for MailHog live updates - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -# Mini QR — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name qr.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org" always; - - location / { - set $upstream_miniqr http://mini-qr:8080; - proxy_pass $upstream_miniqr; - proxy_hide_header X-Frame-Options; - 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; - } -} - -# Excalidraw — allows iframe embedding from admin (app.cmlite.org) -server { - listen 80; - server_name draw.cmlite.org; - add_header Content-Security-Policy "frame-ancestors 'self' app.cmlite.org" always; - - location / { - set $upstream_excalidraw http://excalidraw-changemaker:80; - proxy_pass $upstream_excalidraw; - proxy_hide_header X-Frame-Options; - 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; - - # WebSocket support for collaboration - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - } -} - -# --- Embed proxy ports (for iframe embedding without DNS/subdomain) --- -# These listen on dedicated ports so the admin GUI can iframe services via -# localhost:PORT, bypassing X-Frame-Options without needing *.localhost DNS. - -server { - listen 8881; - location / { - set $upstream_nocodb http://changemaker-v2-nocodb:8080; - proxy_pass $upstream_nocodb; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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; - } -} - -server { - listen 8882; - location / { - set $upstream_n8n http://n8n-changemaker:5678; - proxy_pass $upstream_n8n; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -server { - listen 8883; - # Increase max body size for large git pushes (2GB) - client_max_body_size 2048M; - location / { - set $upstream_gitea http://gitea-changemaker:3000; - proxy_pass $upstream_gitea; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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; - } -} - -server { - listen 8884; - location / { - set $upstream_mailhog http://mailhog-changemaker:8025; - proxy_pass $upstream_mailhog; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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 Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } -} - -server { - listen 8885; - location / { - set $upstream_miniqr http://mini-qr:8080; - proxy_pass $upstream_miniqr; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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; - } -} - -# Excalidraw embed proxy (port 8886) -server { - listen 8886; - location / { - set $upstream_excalidraw http://excalidraw-changemaker:80; - proxy_pass $upstream_excalidraw; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - 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; - - # WebSocket support for collaboration - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_http_version 1.1; - } -} - -# Admin GUI — app subdomain -server { - listen 80; - server_name app.cmlite.org app.betteredmonton.org; - add_header X-Frame-Options "SAMEORIGIN" always; - - location / { - set $upstream_admin http://changemaker-v2-admin:3000; - proxy_pass $upstream_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; - # WebSocket support for Vite HMR - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # Media API endpoints (must come BEFORE /api/ for longest prefix match) - location /api/media/ { - set $upstream_media http://changemaker-media-api:4100; - proxy_pass $upstream_media; - 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; - - # Large upload support - client_max_body_size 10G; - proxy_read_timeout 3600s; - proxy_connect_timeout 75s; - proxy_request_buffering off; - - # WebSocket support - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # API (Express) - location /api/ { - set $upstream_api http://changemaker-v2-api:4000; - proxy_pass $upstream_api; - 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; - } -} - -# MkDocs built static site — root domain -server { - listen 80; - server_name cmlite.org; - - location / { - set $upstream_site http://mkdocs-site-server-changemaker:80; - proxy_pass $upstream_site; - 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; - } -} - -# Root domain — routes to admin GUI (supports custom DOMAIN env var) -server { - listen 80; - server_name betteredmonton.org; - add_header X-Frame-Options "SAMEORIGIN" always; - - location / { - set $upstream_admin http://changemaker-v2-admin:3000; - proxy_pass $upstream_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; - # WebSocket support for Vite HMR - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # Media API endpoints (must come BEFORE /api/ for longest prefix match) - location /api/media/ { - set $upstream_media http://changemaker-media-api:4100; - proxy_pass $upstream_media; - 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; - - # Large upload support - client_max_body_size 10G; - proxy_read_timeout 3600s; - proxy_connect_timeout 75s; - proxy_request_buffering off; - - # WebSocket support - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - } - - # API (Express) - location /api/ { - set $upstream_api http://changemaker-v2-api:4000; - proxy_pass $upstream_api; - 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; - } -} - -# Homepage dashboard -server { - listen 80; - server_name home.cmlite.org; - add_header X-Frame-Options "SAMEORIGIN" always; - - location / { - set $upstream_homepage http://homepage-changemaker:3000; - proxy_pass $upstream_homepage; - 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; - } -}