# nginx **Repository Path**: LoveAI_1/nginx ## Basic Information - **Project Name**: nginx - **Description**: 反代 - **Primary Language**: Docker - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-24 - **Last Updated**: 2026-04-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Caddy 反向代理 基于 Docker + Caddy 2 的反向代理,按域名把流量分发到不同的后端服务。 配置极简(主 Caddyfile 100 行以内),支持 SSE 流式、WebSocket、HTTP/2、HTTP/3。 > 本项目目录名仍叫 `nginx` 是历史原因,实际运行的是 Caddy。原 Nginx 配置保留在 `conf.d/` 和 `snippets/` 目录下作为归档,不再被使用。 ## 当前路由 | 对外域名 | 上游 | 用途 | | --- | --- | --- | | `proxy.changhuai.vip` | `http://43.163.218.91:8989` | kiro-proxy | | `japan.changhuai.vip` | `http://43.163.218.91:3000` | new-api | IP 直连或未知域名访问一律断连(`abort`),不泄露站点。 ## 目录结构 ``` nginx/ ├── docker-compose.yml Caddy 容器编排 ├── Caddyfile 所有路由 / TLS / 日志配置(核心文件) ├── deploy.sh 一键部署脚本 ├── certs/ TLS 证书(Cloudflare Origin 通配 *.changhuai.vip) │ ├── changhuai.vip.crt │ └── changhuai.vip.key ├── logs/ 访问/错误日志(容器写入宿主) ├── conf.d/ [归档] 原 Nginx 站点配置 └── snippets/ [归档] 原 Nginx 代理公共片段 ``` ## 部署 **前置条件**: - `docker` + `docker compose v2` - 云商安全组放行 TCP `80` 和 `443` - DNS A 记录指向本机公网 IP - 证书文件放到 `certs/` 下(当前使用 Cloudflare Origin 通配证书) **一键启动**: ```bash cd /path/to/nginx ./deploy.sh up ``` 脚本会: 1. 校验 Caddyfile 语法(语法错直接报错退出) 2. 检查证书文件是否就位 3. `docker compose up -d` 启动 4. 打印容器状态 + 证书到期时间 + 端口监听 **首次验证**(不依赖 DNS): ```bash # 应返回 200 或上游自己的状态码 curl -I -k -H "Host: proxy.changhuai.vip" https://127.0.0.1/ curl -I -k -H "Host: japan.changhuai.vip" https://127.0.0.1/ # 直接用 IP 访问应该连接失败(abort 兜底) curl -I http://127.0.0.1/ ``` ## 日常维护 ### 改 Caddyfile → 热加载 ```bash ./deploy.sh reload ``` 脚本会先 `caddy validate` 校验语法,通过了才 `caddy reload`(不断现有连接)。 ### 改 docker-compose.yml → 重建容器 端口映射、数据卷、镜像版本等变化,必须重建: ```bash ./deploy.sh up ``` ### 添加新站点 编辑 `Caddyfile`,复制底部的"新增站点模板"段落,改 3 处: ```caddyfile your-new-domain.changhuai.vip { import cf_origin_cert request_body { max_size 100MB } log { output file /var/log/caddy/your-new-domain.access.log { roll_size 50mb roll_keep 5 } } reverse_proxy UPSTREAM_IP:UPSTREAM_PORT { import upstream_common } } ``` 然后 `./deploy.sh reload`。DNS 记得加 A 记录(如果不是通配)。 ### 查日志 ```bash # 容器日志(Caddy 运行时输出) ./deploy.sh logs # 按站点的访问日志(JSON 格式,宿主机直读,自动按 50MB 切片) tail -f logs/proxy.changhuai.vip.access.log tail -f logs/japan.changhuai.vip.access.log # 格式化 JSON 日志(需要 jq) tail -f logs/proxy.changhuai.vip.access.log | jq . ``` ### 其他命令 ```bash ./deploy.sh test # 只校验 Caddyfile 语法,不部署 ./deploy.sh status # 容器状态 + 证书到期 + 端口 ./deploy.sh restart # 硬重启(很少用,reload 足够) ./deploy.sh down # 停掉容器(数据卷保留) ./deploy.sh pull # 拉最新 Caddy 镜像并重建 ``` ## 证书方案 当前使用 **Cloudflare Origin Certificate**(通配 `*.changhuai.vip`,15 年有效,无需续期)。 ``` certs/ ├── changhuai.vip.crt # CF Origin 证书(含中间链) └── changhuai.vip.key # CF Origin 私钥 ``` ### 切换到 Let's Encrypt 自动签发 如果不想用 CF Origin,让 Caddy 自动申请 LE 证书(零配置): 1. 把 Caddyfile 里的 `auto_https disable_certs` 删掉(或改成 `auto_https on`) 2. 移除每个站点里的 `import cf_origin_cert`(或改成 `tls your-email@example.com`) 3. 删掉 `(cf_origin_cert) { ... }` 片段 4. `./deploy.sh reload` Caddy 会自动: - 向 Let's Encrypt 申请证书(需 80 端口可达) - 每 60 天自动续期 - 证书存在 `caddy-data` volume 里(docker volume) **前提**:域名真实解析到本机公网 IP,且 80 端口通(LE 走 HTTP-01 挑战)。 ## 架构要点 ### 同机部署优化 如果 Caddy 和上游服务在**同一台服务器**(当前就是),走公网 IP 回程不划算。方法: 1. `docker-compose.yml` 打开 `extra_hosts` 那几行 2. `Caddyfile` 里的 `43.163.218.91` 全部替换成 `host.docker.internal` 3. `./deploy.sh up` 重建容器 这样流量走宿主机 loopback,延迟更低、不吃公网带宽。 ### 为什么选 Caddy 而不是 Nginx | 对比点 | Nginx | Caddy | | --- | --- | --- | | 配置量 | 原 conf.d 3 个文件 + snippets 共 ~50 行 | 单一 Caddyfile ~100 行(含注释和模板) | | HTTPS 自动化 | 需 certbot + cron / acme.sh | 内建,一行 `tls email@x.com` 就自动申请 | | HTTP/3 | 需要额外模块 + 重编译 | 默认启用 | | 日志切片 | 要么装 logrotate,要么外部脚本 | 内建 `roll_size/roll_keep` | | 热加载 | `nginx -s reload` | `caddy reload` | | 学习曲线 | 熟悉 | 入门更快,老手要查语法 | ## 故障排查 | 现象 | 大概率原因 | | --- | --- | | 外网访问超时 | 云商**安全组**没放 80/443 | | 能 ping 通域名但 curl 连不上 | DNS 没生效 / 指错 IP;或容器没起(`./deploy.sh status`) | | 浏览器 502 Bad Gateway | 上游服务挂了。宿主机 `curl http://上游IP:端口` 验证 | | 浏览器 504 Gateway Timeout | 上游响应超过 1h,或上游真卡死 | | 流式输出一次性才返回 | Caddy 的 `flush_interval -1` 漏配了,检查 `upstream_common` 片段 | | WebSocket 连不上 | Caddy 2 默认支持 WS,不需要显式配。还不行看上游是否支持 | | 改了 Caddyfile 没生效 | 忘了 `./deploy.sh reload`;或改的是 `docker-compose.yml`(要 `up`) | | 启动失败 | `./deploy.sh logs` 看报错;多半 Caddyfile 语法错,先 `./deploy.sh test` | | `tls: unknown certificate` | 证书文件路径错了,或文件不可读(检查容器里 `/etc/caddy/certs/`) |