Files
ITOSMPiano-BachToBasics/frontend/nginx.conf
T
이창현 0522e48013 곡 보관함과 악보 학습 기능을 보완
업로드 형식을 MIDI와 MusicXML과 MXL 및 PDF로 확장하고 파일별 검증을 추가했다.

AlphaTab 악보 자산과 Nginx MIME 설정을 보완해 운영에서 오선과 음표가 표시되도록 수정했다.

공개 도메인 클래식과 난이도별 연습 편곡 7개를 같은 제목별로 묶고 출처와 운영 검증 결과를 문서화했다.

검사: TypeScript 검사와 Vitest 67개 및 Vite 운영 빌드 통과. 운영 브라우저 악보 표시와 네 가지 업로드 검증 형식 확인.
백업: /home/syskiller/piano/backups/bach-to-basics/20261003-1545-sheet-upload
운영 반영: 완료
2026-10-03 16:15:00 +09:00

80 lines
4.0 KiB
Nginx Configuration File

# Bach to Basics: nginx config for the static frontend container.
#
# Serves the built React app and proxies /api/* to the backend service.
# Backend hostname "backend" is resolved via Docker Compose's network.
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# ── Security headers ────────────────────────────────────────────────────
# These are set here (server block) so they apply to all responses that
# don't have their own add_header directives.
# NOTE: nginx does NOT inherit server-level add_header into location blocks
# that define their own add_header (e.g. /assets/). Those blocks repeat
# the security headers explicitly to avoid the inheritance pitfall.
# /api/ is intentionally excluded - the FastAPI backend sets its own.
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# SPA fallback: any route that isn't a real file goes to index.html
location / {
try_files $uri $uri/ /index.html;
}
# PWA 시작 문서와 서비스 워커는 매번 최신 상태를 확인한다. 해시가 붙은
# 정적 자산만 장기 캐시하므로 배포 뒤 예전 화면이 계속 남지 않는다.
location = /index.html {
expires -1;
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
}
location ~ ^/(sw\.js|registerSW\.js|manifest\.webmanifest)$ {
expires -1;
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
}
# AlphaTab의 Worker와 AudioWorklet은 ES 모듈이다. nginx 기본 MIME 표에
# mjs가 없으면 브라우저가 nosniff 정책에 따라 실행을 차단한다.
location ~* \.mjs$ {
default_type application/javascript;
expires 1y;
add_header Cache-Control "public, immutable" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
}
# API proxy, strips the /api prefix on the way through
location /api/ {
proxy_pass http://backend: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 X-API-Key "__BACKEND_API_KEY__";
# Sample / soundfont uploads can be large
client_max_body_size 60M;
# OMR + transcription can take a while
proxy_read_timeout 300s;
}
# Cache static assets aggressively (Vite hashes filenames).
# Repeats security headers because this block defines its own add_header
# (nginx would otherwise drop the server-level ones here).
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
}
}