diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 1cf768b..b6c83d1 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -7,7 +7,7 @@ set -euo pipefail # nginx owns the externally exposed port (Cloud Run injects PORT; default 8000). export PORT="${PORT:-8000}" -envsubst '${PORT}' < /app/docker/nginx.conf.template > /etc/nginx/conf.d/default.conf +envsubst '${PORT}' < /app/docker/nginx.conf.template > /app/docker/nginx.conf # Internal Node server on a fixed loopback port, kept distinct from nginx's PORT # so config.ts's INTERNAL_URL (http://127.0.0.1:${PORT}) resolves to the server @@ -15,7 +15,7 @@ envsubst '${PORT}' < /app/docker/nginx.conf.template > /etc/nginx/conf.d/default PORT=8787 node /app/dist/index.js & node_pid=$! -nginx -g 'daemon off;' & +nginx -c /app/docker/nginx.conf -g 'daemon off;' & nginx_pid=$! # Whichever process exits first, stop the other and fail so the container exits. diff --git a/docker/nginx.conf.template b/docker/nginx.conf.template index 43bc89f..bf48e0f 100644 --- a/docker/nginx.conf.template +++ b/docker/nginx.conf.template @@ -4,45 +4,61 @@ # and forwards /api and /socket.io (with WebSocket upgrade) to the internal Node # server on loopback:8787. ${PORT} is rendered by docker-entrypoint.sh via # `envsubst '${PORT}'`, which leaves nginx's own $-vars ($host/$uri/...) intact. -server { - listen ${PORT}; - server_name _; - - root /app/ui-dist; - index index.html; - - # Allow uploads up to 50MB (plus multipart overhead). The upstream Node - # server enforces the authoritative per-file limit via multer. - client_max_body_size 55m; - - # REST + internal-egress API. No path rewrite: the full /api/... path is - # passed through, matching Vite's prefix proxy key "/api". - location /api { - proxy_pass http://127.0.0.1:8787; - 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; - } +# The config is self-contained. +worker_processes auto; +pid /run/tangent-shell.nginx.pid; +error_log /dev/stderr warn; - # Socket.IO transport. The Upgrade/Connection headers reproduce Vite's - # `ws: true`, and the long read timeout keeps idle WebSockets alive. - location /socket.io { - proxy_pass http://127.0.0.1:8787; - 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_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_read_timeout 86400; - } +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + access_log /dev/stdout; + sendfile on; + + server { + listen ${PORT}; + server_name _; + + root /app/ui-dist; + index index.html; + + # Allow uploads up to 50MB (plus multipart overhead). The upstream Node + # server enforces the authoritative per-file limit via multer. + client_max_body_size 55m; + + # REST + internal-egress API. No path rewrite: the full /api/... path is + # passed through, matching Vite's prefix proxy key "/api". + location /api { + proxy_pass http://127.0.0.1:8787; + 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; + } + + # Socket.IO transport. The Upgrade/Connection headers reproduce Vite's + # `ws: true`, and the long read timeout keeps idle WebSockets alive. + location /socket.io { + proxy_pass http://127.0.0.1:8787; + 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_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 86400; + } - # SPA history fallback: serve the requested asset if it exists, otherwise - # hand back index.html so client-side routing can take over. - location / { - try_files $uri $uri/ /index.html; + # SPA history fallback: serve the requested asset if it exists, otherwise + # hand back index.html so client-side routing can take over. + location / { + try_files $uri $uri/ /index.html; + } } }