nginx-proxy-ai/CLAUDE.md

270 lines
7.0 KiB
Markdown
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.

# CLAUDE.md — nginx-proxy-ai
tlyq.ai 反向代理服务,管理所有子站点的 SSL 终止、路由转发和性能优化。
## 项目概述
nginx-proxy-ai 是 tlyq.ai 域名的统一入口,负责:
- SSL/TLS 终止(所有 HTTPS 流量)
- 反向代理到后端 Docker 容器
- Gzip 压缩
- 静态资源缓存
- HTTP → HTTPS 强制跳转
## SSL 证书配置(必遵)
### 证书来源
| 证书路径 | 类型 | 用途 |
|---------|------|------|
| `/etc/letsencrypt/live/www.tlyq.ai/` | Let's Encrypt | **所有站点共用** |
| `/etc/letsencrypt/live/www.tlyq.ai-0001/` | Let's Encrypt | SSO 站点专用 |
### ⚠️ 禁止事项
1. **禁止使用 CloudFlare Origin 证书**:这是自签名证书,浏览器不信任
2. **禁止手动放置证书文件**:必须通过 certbot 申请
3. **禁止修改 `/etc/letsencrypt/` 目录权限**
### 新增站点证书流程
1. 申请证书:
```bash
ssh txjp "certbot certonly --webroot -w /var/www/html -d new-site.tlyq.ai"
```
2. 配置 nginx 引用现有证书(推荐共用 `www.tlyq.ai`
```nginx
ssl_certificate /etc/letsencrypt/live/www.tlyq.ai/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.tlyq.ai/privkey.pem;
```
3. 重载配置:
```bash
ssh txjp "docker exec nginx-ai nginx -s reload"
```
### 证书续期机制
证书续期通过 **systemd timer** 自动管理,无需人工干预。
#### 工作原理
```
systemd timer (snap.certbot.renew.timer)
↓ 每天 01:30 和 22:32 触发
systemd service (snap.certbot.renew.service)
↓ 执行
certbot renew --timer="00:00~24:00/2"
↓ 续期成功后
deploy hook → docker exec nginx-ai nginx -s reload
```
#### 关键文件
| 组件 | 路径 | 说明 |
|------|------|------|
| Timer | `/etc/systemd/system/snap.certbot.renew.timer` | 定时触发器 |
| Service | `/etc/systemd/system/snap.certbot.renew.service` | 执行续期的服务 |
| Hook | `/etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh` | 续期后重载 nginx |
#### Timer 配置
```ini
[Timer]
OnCalendar=*-*-* 01:30 # 每天 01:30
OnCalendar=*-*-* 22:32 # 每天 22:32
```
每天检查两次,距离到期 < 30 天时自动续期
#### 常用管理命令
```bash
# 查看定时器状态
ssh txjp "systemctl status snap.certbot.renew.timer"
# 查看下次运行时间
ssh txjp "systemctl list-timers snap.certbot.renew.timer"
# 手动触发续期
ssh txjp "systemctl start snap.certbot.renew.service"
# 查看续期日志
ssh txjp "journalctl -u snap.certbot.renew.service --since '1 hour ago'"
# 检查证书有效期
ssh txjp "openssl x509 -in /etc/letsencrypt/live/www.tlyq.ai/fullchain.pem -noout -dates"
# 测试续期(不实际续期)
ssh txjp "certbot renew --dry-run"
```
## 文件结构
```
nginx-proxy-ai/
├── nginx.conf # 主配置(全局优化参数)
├── nginx-local.conf # 本地测试配置
├── docker-compose.yml # 生产 Docker 配置
├── docker-compose.local.yml # 本地测试 Docker 配置
├── conf.d/ # 站点反向代理配置
│ ├── www-ai.conf # www.tlyq.ai
│ ├── cloud-ai.conf # cloud.tlyq.ai纯静态
│ ├── token-ai.conf # token.tlyq.ai纯静态
│ ├── issue-ai.conf # issue.tlyq.ai
│ ├── assets-ai.conf # assets.tlyq.ai
│ ├── git-ai.conf # git.tlyq.aiGitea
│ ├── oa-ai.conf # oa.tlyq.ai
│ ├── sso-ai.conf # sso.tlyq.aiAuthelia
│ ├── monitor-ai.conf # monitor.tlyq.ai
│ ├── root-domain.conf # tlyq.ai → www.tlyq.ai 跳转
│ └── letsencrypt.conf # ACME HTTP-01 验证
├── certs/ # 本地测试自签名证书(不纳入生产)
└── static/ # 静态文件目录
```
## 部署流程
### 生产部署txjp 服务器)
```bash
# 1. 上传配置(排除本地测试文件)
rsync -avz --exclude='node_modules' --exclude='.git' \
--exclude='nginx-local.conf' --exclude='docker-compose.local.yml' \
--exclude='certs/' \
./ txjp:/root/docker/nginx-proxy-ai/
# 2. 验证配置
ssh txjp "docker exec nginx-ai nginx -t"
# 3. 平滑重载
ssh txjp "docker exec nginx-ai nginx -s reload"
```
### 本地测试
```bash
docker compose -f docker-compose.local.yml up -d
```
## 性能优化参数
### 全局优化nginx.conf http 块)
```nginx
# IO 优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Keepalive
keepalive_timeout 65;
keepalive_requests 1000;
# 客户端超时
client_max_body_size 16m;
client_body_buffer_size 128k;
client_header_timeout 30s;
send_timeout 30s;
# Gzip
gzip on;
gzip_min_length 1k;
gzip_comp_level 5;
gzip_types text/plain text/css application/json application/javascript application/xml image/svg+xml;
```
### SSL 安全配置
```nginx
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;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets on;
server_tokens off;
```
### 反代默认参数
```nginx
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 Connection "";
proxy_connect_timeout 3s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
proxy_buffer_size 16k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
```
## 常用排查命令
```bash
# 配置语法检查
docker exec nginx-ai nginx -t
# 查看完整合并配置
docker exec nginx-ai nginx -T
# 查看 SSL 配置
docker exec nginx-ai nginx -T | grep -E 'ssl_protocols|ssl_ciphers|ssl_certificate'
# 测试 SSL 连接
echo | openssl s_client -connect 127.0.0.1:443 -servername www.tlyq.ai 2>/dev/null | grep -E 'Protocol|Cipher'
# 检查证书有效期
ssh txjp "openssl x509 -in /etc/letsencrypt/live/www.tlyq.ai/fullchain.pem -noout -dates"
```
## 故障排查
### SSL 不安全提示
1. 检查证书是否为 Let's Encrypt
```bash
ssh txjp "openssl x509 -in /etc/letsencrypt/live/www.tlyq.ai/fullchain.pem -noout -issuer"
```
应显示 `Let's Encrypt`而非 `CloudFlare`
2. 检查 SSL 协议和加密套件
```bash
docker exec nginx-ai nginx -T | grep -E 'ssl_protocols|ssl_ciphers'
```
必须配置 `ssl_protocols TLSv1.2 TLSv1.3`
### 502 Bad Gateway
1. 检查后端容器是否运行
```bash
docker ps | grep -E 'www-ai|assets-ai|issue-ai'
```
2. 检查容器网络连通性
```bash
docker exec nginx-ai ping assets-ai
```
### 配置不生效
1. 确认配置语法正确
```bash
docker exec nginx-ai nginx -t
```
2. 确认已重载
```bash
docker exec nginx-ai nginx -s reload
```
3. 确认容器挂载路径正确
```bash
docker inspect nginx-ai | grep -A5 Mounts
```