# ============================================================ # 预览环境 Nginx 配置模板 # 支持 *.preview.xiaoxiajianji.com 通配符子域名 # # 使用方法: # 1. 将本文件复制到 Nginx 配置目录(如 /etc/nginx/conf.d/preview.conf) # 2. 根据实际情况修改域名和 API 地址 # 3. 运行 nginx -t 测试配置 # 4. 运行 nginx -s reload 重载配置 # # 前置条件: # - DNS 已配置 *.preview.xiaoxiajianji.com 指向本服务器 # - 预览根目录已创建:/var/www/preview/ # - 每个 PR 的静态文件放在 /var/www/preview/pr-{N}/ 下 # ============================================================ # ---- 变量定义 ---- # 从子域名中提取 PR 号(如 pr-123.preview -> pr-123) map $host $preview_pr { default ""; ~^(?pr-\d+)\.preview\.xiaoxiajianji\.com$ $pr; } # ---- HTTP 服务器(80端口) ---- server { listen 80; server_name *.preview.xiaoxiajianji.com; # 根目录根据子域名动态映射 root /var/www/preview/$preview_pr; # 索引文件 index index.html; # 字符集 charset utf-8; # 访问日志 access_log /var/log/nginx/preview_access.log; error_log /var/log/nginx/preview_error.log warn; # 如果子域名格式不正确,返回404 if ($preview_pr = "") { return 404; } # 如果预览目录不存在,返回404 if (!-d $document_root) { return 404; } # ---- API 反向代理到 staging 环境 ---- location /api/ { proxy_pass https://staging-api.xiaoxiajianji.com/api/; proxy_http_version 1.1; # 请求头设置 proxy_set_header Host staging-api.xiaoxiajianji.com; 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-Forwarded-Host $host; # 超时设置 proxy_connect_timeout 30s; proxy_send_timeout 60s; proxy_read_timeout 60s; # 缓冲设置 proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; # 重定向跟随 proxy_redirect off; # WebSocket 支持(如需要,取消注释) # proxy_set_header Upgrade $http_upgrade; # proxy_set_header Connection "upgrade"; } # ---- 生成文件代理(如需要) ---- # location /generated-files/ { # proxy_pass https://staging-api.xiaoxiajianji.com/generated-files/; # proxy_http_version 1.1; # proxy_set_header Host staging-api.xiaoxiajianji.com; # 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; # } # ---- 静态资源缓存 ---- location /assets/ { expires 7d; add_header Cache-Control "public, max-age=604800, immutable"; try_files $uri =404; } # ---- SPA 路由支持 ---- location / { try_files $uri $uri/ /index.html; } # ---- 安全相关响应头 ---- add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; # ---- 禁止隐藏文件访问 ---- location ~ /\. { deny all; access_log off; log_not_found off; } # ---- 禁止敏感文件访问 ---- location ~* \.(env|log|sql|bak|swp|tmp|zip|tar|gz)$ { deny all; access_log off; log_not_found off; } } # ============================================================ # HTTPS 服务器配置(可选,需要 SSL 证书) # # 推荐使用 Let's Encrypt 通配符证书: # certbot certonly --dns-xxx -d "*.preview.xiaoxiajianji.com" # # 启用方法:取消下方注释,并修改证书路径 # ============================================================ # # server { # listen 443 ssl http2; # server_name *.preview.xiaoxiajianji.com; # # # SSL 证书配置 # ssl_certificate /etc/letsencrypt/live/preview.xiaoxiajianji.com/fullchain.pem; # ssl_certificate_key /etc/letsencrypt/live/preview.xiaoxiajianji.com/privkey.pem; # # # SSL 安全配置 # ssl_protocols TLSv1.2 TLSv1.3; # ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; # ssl_prefer_server_ciphers off; # ssl_session_cache shared:SSL:10m; # ssl_session_timeout 10m; # ssl_session_tickets off; # # # OCSP Stapling # ssl_stapling on; # ssl_stapling_verify on; # # # 根目录根据子域名动态映射 # root /var/www/preview/$preview_pr; # # # 索引文件 # index index.html; # # # 字符集 # charset utf-8; # # # 访问日志 # access_log /var/log/nginx/preview_ssl_access.log; # error_log /var/log/nginx/preview_ssl_error.log warn; # # # 如果子域名格式不正确,返回404 # if ($preview_pr = "") { # return 404; # } # # # 如果预览目录不存在,返回404 # if (!-d $document_root) { # return 404; # } # # # API 反向代理到 staging 环境 # location /api/ { # proxy_pass https://staging-api.xiaoxiajianji.com/api/; # proxy_http_version 1.1; # proxy_set_header Host staging-api.xiaoxiajianji.com; # 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-Forwarded-Host $host; # proxy_connect_timeout 30s; # proxy_send_timeout 60s; # proxy_read_timeout 60s; # proxy_buffering on; # proxy_buffer_size 4k; # proxy_buffers 8 4k; # } # # # 静态资源缓存 # location /assets/ { # expires 7d; # add_header Cache-Control "public, max-age=604800, immutable"; # try_files $uri =404; # } # # # SPA 路由支持 # location / { # try_files $uri $uri/ /index.html; # } # # # 安全相关响应头 # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # add_header X-Frame-Options "SAMEORIGIN" always; # add_header X-Content-Type-Options "nosniff" always; # add_header X-XSS-Protection "1; mode=block" always; # add_header Referrer-Policy "strict-origin-when-cross-origin" always; # # # 禁止隐藏文件访问 # location ~ /\. { # deny all; # access_log off; # log_not_found off; # } # # # 禁止敏感文件访问 # location ~* \.(env|log|sql|bak|swp|tmp|zip|tar|gz)$ { # deny all; # access_log off; # log_not_found off; # } # }