Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docker/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ 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
# itself rather than to nginx.
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.
Expand Down
92 changes: 54 additions & 38 deletions docker/nginx.conf.template
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
Loading