Docker Compose 部署 Nginx 反向代理与 Cloudflare 建坑避坑指南
Docker Compose 部署 Nginx 反向代理与 Cloudflare 建坑避坑指南
在自建服务或部署 Docker 应用时,我们经常需要通过 Nginx 进行反向代理,将二级域名解析到具体的容器服务上。本文将以部署一个 Docker 镜像代理服务 为例,完整记录通过 Docker Compose + Nginx 实现域名解析、SSL 证书配置以及解决常见 Cloudflare 301 重定向循环 和 404 响应 的实战过程。
1. 架构与准备
- 域名:
registry.example.com(DNS 解析至服务器 IP,通过 Cloudflare 代理) - 后端服务:运行在宿主机
18234端口的 Docker Registry 代理容器 - Nginx:通过 Docker / Docker Compose 部署,监听 80 和 443 端口
2. Nginx 配置文件
在宿主机的配置文件目录(例如 ./conf.d/registry.conf)中创建对应的反向代理配置:
1 | # HTTP 80 端口:重定向至 HTTPS & ACME 证书校验 |
3. Docker Compose 配置
创建 docker-compose.yml 文件:
1 | version: '3.8' |
执行启动命令:
1 | docker compose up -d |
4. 踩坑与排查全记录
坑一:curl 报 ERR_TOO_MANY_REDIRECTS / 无限 301 循环
现象:访问域名时,
curl -IL [https://registry.example.com](https://registry.example.com)提示重定向超过最大次数限制。原因:Cloudflare 的 SSL/TLS 模式默认设为了 Flexible(灵活)。
客户端使用 HTTPS 请求 Cloudflare。
Cloudflare 强制使用 HTTP (80端口) 去连接源站 Nginx。
Nginx 触发了 80 端口下的
return 301 https://...。Cloudflare 收到 301 后再次用 HTTP 请求源站,陷入无限死循环。
解决方案:
登录 Cloudflare Dashboard -> SSL/TLS -> Overview。
将加密模式从 Flexible 改为 Full 或 Full (strict)。
注:改动为 Full 是 Cloudflare 的全局标准操作,不会损坏同域名下其他配置了 SSL 的服务。
坑二:浏览器/Curl 访问根路径返回 404
- 现象:解决 301 循环后,访问
[https://registry.example.com](https://registry.example.com)直接返回HTTP 404。 - 原因:后端服务(如 Docker Registry 镜像代理)仅实现了标准的 API 接口(如
/v2/),并没有配置根目录/的前端 Web 页面。 - 验证方法:
对后端专用的 API 接口发起请求测试:
1 | curl -i https://registry.example.com/v2/ |
响应结果:
1 | 401 Unauthorized |
返回 401 Unauthorized 并带有 docker-distribution-api-version: registry/2.0 响应头,说明这完全符合 Docker Registry v2 的规范,反向代理已成功连通!
5. 服务验证与使用
配置完成后,可以直接使用该域名进行 Docker 镜像拉取:
1 | # 直接拉取镜像 |
6. 总结
- Docker 容器反代宿主机端口:Linux 环境下需要在
docker-compose.yml中添加extra_hosts: ["host.docker.internal:host-gateway"]。 - Cloudflare CDN + Nginx 重定向:源站配置了 HTTP->HTTPS 强制跳转时,Cloudflare 的 SSL 模式必须设为 Full 或 Full (strict)。
- 正确评估 404/401 状态码:对于纯 API 服务(如 Docker Registry),根路径 404 或
/v2/路径返回 401 均属符合规范的正常响应,无需过度怀疑 Nginx 转发失败。
