server { listen 80; server_name demo.castad.net; if ($bad_bot) { return 403; } access_log /log/nginx/demo.castad.net.gunicorn_access.log main; error_log /log/nginx/demo.castad.net.gunicorn_error.log warn; # if ($host !~* ^(domain\.com|www\.domain\.com)$) { # return 444; # } # 프론트엔드 정적 파일 루트 root /www/o2o-castad-frontend/dist; index index.html; # Django media location /media { autoindex off; gzip_static on; expires max; #alias /www/django_sample/media; alias /www/o2o-castad-backend/media; # your Django project's media files - amend as required #include /etc/nginx/mime.types; } location /static { autoindex off; gzip_static on; expires max; #alias /www/django_sample/static; # normally static folder is named as /static alias /www/o2o-castad-backend/static; # your Django project's static files - amend as required #include /etc/nginx/mime.types; } location /api/ { autoindex off; # upstream 연결 풀 사용 (nginx.conf에서 정의) proxy_pass http://uvicorn-app:8000/; # HTTP/1.1 사용 (keepalive 연결 필수) proxy_http_version 1.1; # WebSocket 지원 및 HTTP keepalive 동시 지원 # - WebSocket: Upgrade 헤더 전달, Connection: upgrade # - 일반 HTTP: Connection: "" (keepalive 유지) proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; # 프록시 헤더 설정 proxy_set_header Host $http_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; # 프록시 캐시 우회 (WebSocket 및 동적 콘텐츠) proxy_cache_bypass $http_upgrade; # 타임아웃 설정 (파일 업로드, AI 생성 등 오래 걸리는 작업용) proxy_connect_timeout 300s; proxy_send_timeout 300s; proxy_read_timeout 300s; # 파일 업로드 설정 client_max_body_size 100M; proxy_request_buffering off; } # Allow Lets Encrypt Domain Validation Program location ^~ /.well-known/acme-challenge/ { allow all; root /www/o2o-castad-backend; } # Block dot file (.htaccess .htpasswd .svn .git .env and so on.) location ~ /\. { deny all; } # Block (log file, binary, certificate, shell script, sql dump file) access. location ~* \.(log|binary|pem|enc|crt|conf|cnf|sql|sh|key|yml|lock)$ { deny all; } # Block access location ~* (composer\.json|composer\.lock|composer\.phar|contributing\.md|license\.txt|readme\.rst|readme\.md|readme\.txt|copyright|artisan|gulpfile\.js|package\.json|phpunit\.xml|access_log|error_log|gruntfile\.js)$ { deny all; } location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { log_not_found off; access_log off; } }