# ISO8601 시간을 "YYYY-MM-DD HH:mm:ss" 형식으로 변환 map $time_iso8601 $time_custom { "~^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})" "$1-$2-$3 $4:$5:$6"; } # Go slog 포맷과 맞춘 JSON 액세스 로그 log_format json_combined escape=json '{' '"time":"$time_custom",' '"level":"INFO",' '"msg":"http_access",' '"svc":"baron-userfront",' '"status":$status,' '"method":"$request_method",' '"path":"$request_uri",' '"latency":"${request_time}s",' '"ip":"$remote_addr",' '"forwarded_for":"$http_x_forwarded_for",' '"user_agent":"$http_user_agent"' '}'; server { listen 5000; absolute_redirect off; port_in_redirect off; root /usr/share/nginx/html; index index.html; include /etc/nginx/mime.types; types { application/javascript mjs; } etag on; brotli off; brotli_static on; error_log /dev/stderr warn; access_log /var/log/nginx/access.log json_combined; # --- Backend API Proxy --- location /api { proxy_pass http://baron_backend:3000; 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; } # --- UserFront Static Files --- location = / { if ($args = "") { return 302 /ko/signin; } add_header Cache-Control "no-cache, max-age=0, must-revalidate"; try_files /index.html =404; } # App shell and Flutter bootstrap files must revalidate on each deployment. location = /index.html { add_header Cache-Control "no-cache, max-age=0, must-revalidate"; try_files /index.html =404; } location ~* ^/(flutter_bootstrap\.js|flutter_service_worker\.js|version\.json|manifest\.json)$ { add_header Cache-Control "no-cache, max-age=0, must-revalidate"; try_files $uri =404; } # Flutter engine files are SDK-versioned by the build and are safe to keep warm. location ~* ^/canvaskit/.*\.(js|wasm)$ { add_header Cache-Control "public, max-age=31536000, immutable"; try_files $uri =404; } # App entrypoints use content hashes after the Docker build optimization step. location ~* "^/main\.dart\.[0-9a-f]{12}\.(js|mjs|wasm)$" { add_header Cache-Control "public, max-age=31536000, immutable"; try_files $uri =404; } location ~* \.(png|ico|svg|webp|woff|woff2)$ { add_header Cache-Control "public, max-age=31536000, immutable"; try_files $uri =404; } # Non-hashed app entrypoints keep browser cache validation without serving stale code after deploy. location ~* \.(js|css|json|mjs|wasm)$ { add_header Cache-Control "no-cache, max-age=0, must-revalidate"; try_files $uri =404; } location / { add_header Cache-Control "no-cache, max-age=0, must-revalidate"; try_files $uri $uri/ /index.html; } }