Files
vscode-workbench/nginx-docker.conf
T

264 lines
11 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
server_tokens off;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# API 目录封面等同源静态资源:必须优先于 SPA fallback,避免返回 index.html。
# 文件来自 frontend public/api-directory/,构建后位于 /usr/share/nginx/html/api-directory/。
location ^~ /api-directory/ {
try_files $uri =404;
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable" always;
types {
image/avif avif;
image/gif gif;
image/jpeg jpg jpeg;
image/png png;
image/svg+xml svg;
image/webp webp;
}
default_type application/octet-stream;
access_log off;
}
# 开启gzip压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript application/json;
# WebSocket 反代(聊天 ws/chat、扫码登录 ws/qr-status → Granian + Channels)
location /ws/ {
proxy_pass http://backend:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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 3600s;
proxy_send_timeout 3600s;
}
# API 反代 → Granian(ADRF 异步视图)
# C-01:精确收窄到后端真实存在的 API 前缀。SPA 路由(/open-api*、/post/*、
# /user-home*、/articles、/learn 列表页等)一律落到下面的 `location /` 回退,
# 不再被宽正则劫持。旧分享链接(/article/:id、/user/:id、/api-detail/* 等)
# 由前端 SPA 内 <Navigate> 重定向承接,nginx 直接放行到 index.html 即可。
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 Content-Type $http_content_type;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 50M;
}
# 后端 user.urls(/user/<action>/):SPA 已迁到 /user-home*,旧 /user/:id 分享
# 链接由前端重定向承接;数字 id 形态放行到 SPA,其余代理到后端
location ~ ^/user/\d+/?$ {
try_files $uri $uri/ /index.html;
}
location ~ ^/user/ {
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 Content-Type $http_content_type;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 50M;
}
# 后端 bug.urls 仅 /bug/reports/*;SPA /bug 与 /bug-detail 放行
location ~ ^/bug/reports/ {
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_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 50M;
}
# 后端 article.urls 仅 articles|my-articles|comments;SPA /post/*、/articles 放行
location ~ ^/article/(articles|my-articles|comments)/ {
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_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 50M;
}
# 后端 learn.urls 子段;SPA /learn 列表页放行
location ~ ^/learn/(courses|chapters|my-courses|my-progress|materials|favorites|cdn)/ {
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_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 50M;
}
# 后端 message.urls(/message/*);SPA /messages(多 s)天然不命中
location ~ ^/message/ {
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_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 50M;
}
# 后端 chat.urls 子段;SPA /chat 本体放行
location ~ ^/chat/(friend-requests|friends|users|conversations|messages|upload|favorite-stickers)/ {
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_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 50M;
}
# 后端 tool.urls(/tool/*);SPA /tool-detail 放行(不以 /tool/ 开头)
location ~ ^/tool/ {
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_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 50M;
}
# 后端 history.urls 仅 records/;SPA /history 列表页放行
location ~ ^/history/records/ {
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_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 50M;
}
# 后端 search 查询串形态(GET /search/?q=);裸 /search(页)与无参 /search/ 放行到 SPA。
# location 按 URI 匹配、看不见 query string,故用 $args 分流。
location = /search/ {
error_page 418 = @spa_fallback;
if ($args = "") { return 418; }
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_read_timeout 60s;
proxy_send_timeout 60s;
}
location ~ ^/search/(suggestions|hot-keywords)/ {
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_read_timeout 60s;
proxy_send_timeout 60s;
}
# 后端 app(changelog)/ logs / shorturl
location ~ ^/(app|logs/api|shorturl)/ {
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_read_timeout 60s;
proxy_send_timeout 60s;
client_max_body_size 50M;
}
# 短链跳转 /s/<code>/:仅短码形态代理,其余(/settings、/shorturl-detail)放行
location ~ ^/s/[^/]+/?$ {
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_read_timeout 60s;
proxy_send_timeout 60s;
}
# Django admin / swagger / redoc / i18n / 测试页
# 生产默认仅内网可达;如需公网管理入口请走独立域名 + IP 白名单 + MFA。
location /admin/ { allow 127.0.0.1; allow 10.0.0.0/8; allow 172.16.0.0/12; allow 192.168.0.0/16; deny all; proxy_pass http://backend:8000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 5M; }
location /swagger { allow 127.0.0.1; allow 10.0.0.0/8; allow 172.16.0.0/12; allow 192.168.0.0/16; deny all; proxy_pass http://backend:8000; proxy_set_header Host $host; }
location /swagger.json { allow 127.0.0.1; allow 10.0.0.0/8; allow 172.16.0.0/12; allow 192.168.0.0/16; deny all; proxy_pass http://backend:8000; proxy_set_header Host $host; }
location /redoc/ { allow 127.0.0.1; allow 10.0.0.0/8; allow 172.16.0.0/12; allow 192.168.0.0/16; deny all; proxy_pass http://backend:8000; proxy_set_header Host $host; }
location /i18n/ { proxy_pass http://backend:8000; proxy_set_header Host $host; }
location /test/ { allow 127.0.0.1; allow 10.0.0.0/8; allow 172.16.0.0/12; allow 192.168.0.0/16; deny all; proxy_pass http://backend:8000; proxy_set_header Host $host; }
# 带哈希指纹的构建产物:永久强缓存(immutable)
location ~* ^/assets/.*\.(js|css|png|jpg|jpeg|gif|webp|avif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# 其他静态资源(public/ 目录:图片/字体等无指纹文件):适中缓存
location ~* \.(png|jpg|jpeg|gif|webp|ico|svg|woff|woff2|ttf|eot)$ {
expires 7d;
add_header Cache-Control "public";
access_log off;
}
# index.html 不缓存,保证发版后立即生效
location = /index.html {
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# SPA 路由回退(放在最后,避免拦截上面的 API 请求)
location / {
try_files $uri $uri/ /index.html;
}
location @spa_fallback {
try_files $uri $uri/ /index.html;
}
}