map $http_upgrade $connection_upgrade { default upgrade; '' close; } upstream backend_upstream { server backend:8000; } upstream runtime_upstream { server runtime:8000; } upstream jupyter_upstream { server jupyter:8888; } server { listen 80; server_name _; client_max_body_size 100m; location = /health { default_type application/json; return 200 '{"status":"ok","service":"gateway"}'; } root /usr/share/nginx/html; index index.html; location / { try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://backend_upstream; 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-Request-ID $request_id; } location = /_jupyter_auth { internal; proxy_pass http://runtime_upstream/internal/v1/jupyter/authorize; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header Cookie $http_cookie; proxy_set_header X-Original-URI $request_uri; proxy_set_header X-Request-ID $request_id; proxy_set_header X-Service-Token "${INTERNAL_SERVICE_TOKEN}"; } location = /jupyter { return 308 /jupyter/; } location ^~ /jupyter/ { auth_request /_jupyter_auth; auth_request_set $jupyter_authorization $upstream_http_x_jupyter_authorization; proxy_pass http://jupyter_upstream; proxy_http_version 1.1; proxy_set_header Authorization $jupyter_authorization; proxy_set_header Host $http_host; proxy_set_header Origin $http_origin; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; 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-Prefix /jupyter; proxy_set_header X-Request-ID $request_id; proxy_buffering off; proxy_request_buffering off; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_redirect off; } }