server { listen 80; server_name _; # Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; root /usr/share/nginx/html; index index.html; # index.html은 캐시 금지 (배포 반영 핵심) location = /index.html { add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"; try_files $uri =404; } # 정적 리소스는 장기 캐시 (Vite 해시 파일) location /assets/ { add_header Cache-Control "public, max-age=31536000, immutable"; try_files $uri =404; } # music media — Nginx가 직접 오디오 파일 서빙 location ^~ /media/music/ { alias /data/music/; expires 30d; add_header Cache-Control "public, max-age=2592000" always; add_header Accept-Ranges bytes always; # 오디오 스트리밍 범위 요청 지원 autoindex off; } # music videos — Nginx가 직접 비디오 파일 서빙 location ^~ /media/videos/ { alias /data/videos/; expires 1d; add_header Cache-Control "public, max-age=86400" always; add_header Accept-Ranges bytes always; # 비디오 스트리밍 범위 요청 지원 autoindex off; } # music API — 변수 기반 proxy_pass + $request_uri로 전체 경로 전달 location /api/music/ { resolver 127.0.0.11 valid=10s; set $music_backend music-lab:8000; 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_read_timeout 660s; proxy_pass http://$music_backend$request_uri; } # realestate API location /api/realestate/ { 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_pass http://realestate-lab:8000/api/realestate/; } # travel thumbnails (generated by travel-proxy, stored in /data/thumbs) location ^~ /media/travel/.thumb/ { alias /data/thumbs/; expires 30d; add_header Cache-Control "public, max-age=2592000, immutable" always; autoindex off; } # travel media (images) - nginx가 직접 파일 서빙 location ^~ /media/travel/ { alias /data/travel/; # ✅ /media/travel/... -> /data/travel/... expires 7d; add_header Cache-Control "public, max-age=604800" always; # 옵션: 폴더리스팅 막기 autoindex off; } # 기타 정적 파일(예: vite.svg 등) 기본 캐시(원하면 조정) location ~* \.(?:ico|png|jpg|jpeg|gif|svg|webp|css|js)$ { add_header Cache-Control "public, max-age=604800"; try_files $uri =404; } # todos API → personal location /api/todos { resolver 127.0.0.11 valid=10s; set $personal_backend personal:8000; 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_pass http://$personal_backend$request_uri; } # blog API → personal location /api/blog/ { resolver 127.0.0.11 valid=10s; set $personal_backend personal:8000; 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_pass http://$personal_backend$request_uri; } # travel API location /api/travel/ { 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_read_timeout 600s; proxy_pass http://travel-proxy:8000/api/travel/; } # stock API location /api/stock/ { 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_pass http://stock-lab:8000/api/stock/; } # trade API (Stock Lab Proxy) location /api/trade/ { 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_pass http://stock-lab:8000/api/trade/; } # blog-marketing API location /api/blog-marketing/ { resolver 127.0.0.11 valid=10s; set $blog_backend blog-lab:8000; 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_read_timeout 120s; proxy_pass http://$blog_backend$request_uri; } # portfolio API (Stock Lab) — trailing slash 유무 모두 매칭 location /api/portfolio { 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_pass http://stock-lab:8000/api/portfolio; } # profile API (Personal Service) location /api/profile/ { resolver 127.0.0.11 valid=10s; set $personal_backend personal:8000; 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_pass http://$personal_backend$request_uri; } # agent-office API + WebSocket location /api/agent-office/ { resolver 127.0.0.11 valid=10s; set $agent_office_backend agent-office:8000; 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 Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 86400s; proxy_pass http://$agent_office_backend$request_uri; } # API 프록시 (여기가 포인트: /api/ 중복 제거) location /api/ { 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_pass http://lotto:8000; } # Fear & Greed Index (CNN 공개 API) # 프로덕션 nginx에서는 아래 proxy_pass 추가 필요: location /ext/feargreed { proxy_pass https://production.dataviz.cnn.io/index/fearandgreed/graphdata; proxy_set_header Host production.dataviz.cnn.io; } # VIX (CBOE 변동성 지수) — Yahoo Finance 공개 API # 프로덕션 nginx에서는 아래 proxy_pass 추가 필요: location /ext/vix { proxy_pass https://query1.finance.yahoo.com/v8/finance/chart/%5EVIX?interval=1d&range=1d; proxy_set_header Host query1.finance.yahoo.com; } # 미국 10년물 국채 금리 (^TNX) — Yahoo Finance # 프로덕션 nginx 설정 필요: location /ext/treasury { proxy_pass https://query1.finance.yahoo.com/v8/finance/chart/%5ETNX?interval=1d&range=1d; proxy_set_header Host query1.finance.yahoo.com; } # WTI 원유 선물 (CL=F) — Yahoo Finance # 프로덕션 nginx 설정 필요: location /ext/wti { proxy_pass https://query1.finance.yahoo.com/v8/finance/chart/CL%3DF?interval=1d&range=1d; proxy_set_header Host query1.finance.yahoo.com; } # Brent 원유 선물 (BZ=F) — Yahoo Finance # 프로덕션 nginx 설정 필요: location /ext/brent { proxy_pass https://query1.finance.yahoo.com/v8/finance/chart/BZ%3DF?interval=1d&range=1d; proxy_set_header Host query1.finance.yahoo.com; } # webhook receiver (handle both /webhook and /webhook/) location = /webhook { 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_pass http://deployer:9000/webhook; } location /webhook/ { 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_pass http://deployer:9000/webhook; } # SPA 라우팅 (마지막에 두는 게 안전) location / { try_files $uri $uri/ /index.html; } # gzip (옵션) gzip on; gzip_types text/plain text/css application/json application/javascript application/xml+rss; gzip_min_length 1024; }