Files
jiu/deploy/nginx-jiu-ali.conf
T
wangjia 607b8aa763 devops: jiu 证书切 certbot webroot 自动续期(letsencrypt live 路径)
ali 上重签 jiu.51yanmei.com(authenticator 由 dns-cloudflare 切 webroot,NS 迁阿里云后
旧方式必失败);certbot-renew.timer 启用 + deploy 钩子自动 reload;dry-run 通过;
EC2 同步的证书副本(/etc/nginx/ssl)已删除。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
2026-07-03 10:55:24 +08:00

140 lines
5.2 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.
# 阿里云独立 nginx 版(宿主机直接终结 TLS,不经 pangolin)。
# 与 nginx-jiu.confEC2 pangolin 容器版,listen 127.0.0.1:8445)等价。
# CI deploy-server.sh 的 ali 分支落到 /etc/nginx/conf.d/jiu.conf。
#
# 2026-07-03 备案通过回切:443 ssljiu.51yanmei.com)为唯一正式入口 + 80→443 跳转。
# 8443 明文过渡口已拆(用户拍板:裸 IP 版 client 从未发过,存量客户端都是 https
# 域名 BASE_URLDNS 回切后自动恢复,8443 无人使用)。
# 证书:/etc/nginx/ssl/jiu.51yanmei.com/2026-07-03 从 EC2 letsencrypt 同步,
# 2026-08-28 到期;续期方案=DNS 已指 ali 后 certbot HTTP-01 webroot,见 baize)。
# 后端上游 = 127.0.0.1:8081(非 8080ali 上 8080 已被 pay 项目 payd 占用;
# 对应 /opt/jiu/config/production.env 的 SERVER_PORT=8081)。
limit_req_zone $binary_remote_addr zone=jiu_pub:10m rate=10r/s;
limit_req_status 429;
server {
# ali nginx 1.24 无 `http2 on;`1.25.1+),用 listen 参数旧语法
listen 443 ssl http2 default_server; # 正式入口(备案后回切 2026-07-03
server_name jiu.51yanmei.com _;
# 证书:certbot webroot 自动续期(certbot-renew.timer 每日 + deploy 钩子 reload
# 2026-07-03 签发,authenticator=webrootdry-run 验证通过)
ssl_certificate /etc/letsencrypt/live/jiu.51yanmei.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/jiu.51yanmei.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# 安全响应头(SEC-P02)。注意 nginx add_header 继承规则:location 内有自己的
# add_header 时会整体覆盖 server 级——故 /images、/app/index.html、/downloads
# 三处各自补了 HSTS。
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Frame-Options SAMEORIGIN always;
add_header X-Content-Type-Options nosniff always;
client_max_body_size 20m;
# certbot HTTP-01 续期通道(webroot 独立目录,不放 marketing——
# deploy-site 的 rsync --delete 会清掉站点目录里的挑战文件)
location ^~ /.well-known/acme-challenge/ {
root /var/www/acme;
}
# 商品图片静态文件
location ^~ /images/ {
alias /opt/jiu/images/;
expires 30d;
add_header Cache-Control "public, immutable";
add_header Strict-Transport-Security "max-age=31536000" always;
}
# 文件导入接口(超时更长)
location ~ ^/api/v1/import/ {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 300s;
}
# 未鉴权公开/登录接口:加最外层 per-IP 限流
location ~ ^/api/v1/(public|auth)/ {
limit_req zone=jiu_pub burst=20 nodelay;
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 30s;
}
# API 反向代理
location ~ ^/(api|health|version) {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 30s;
}
# Flutter 管理端(仅 /app/ 前缀)
location /app/ {
alias /opt/jiu/web/;
index index.html;
try_files $uri $uri/ /app/index.html;
}
location = /app/index.html {
alias /opt/jiu/web/index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Strict-Transport-Security "max-age=31536000" always;
expires 0;
}
# 公开商品详情页(扫码跳转)→ 后端注入 OG 标签
location ~ ^/product/ {
limit_req zone=jiu_pub burst=20 nodelay;
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 30s;
}
# Flutter base-href=/app/ 会把 /product/:id 重写为 /app/product/:id
location ~ ^/app/product/ {
limit_req zone=jiu_pub burst=20 nodelay;
rewrite ^/app(/product/.+)$ $1 break;
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 30s;
}
# 桌面客户端安装包下载
location /downloads/ {
alias /opt/jiu/downloads/;
add_header Content-Disposition "attachment";
add_header Cache-Control "no-cache";
add_header Strict-Transport-Security "max-age=31536000" always;
autoindex off;
}
# 营销站点兜底
location / {
root /opt/jiu/marketing;
try_files $uri $uri.html $uri/index.html /index.html;
}
}
# 80 → 443 跳转(仅 jiu 域名;51yanmei.com 门户 80 在 51yanmei.conf 自管)。
# ACME 挑战必须在跳转前放行(HTTP-01 走 80)。
server {
listen 80;
server_name jiu.51yanmei.com;
location ^~ /.well-known/acme-challenge/ {
root /var/www/acme;
}
location / {
return 301 https://$host$request_uri;
}
}