Loading...

文章背景图

nginx-proxy:Docker 自动化 Nginx 反向代理部署与使用指南

2026-10-27
0
- 字
- 分钟
|

nginx-proxy:Docker 自动化 Nginx 反向代理部署与使用指南

一、项目官方信息

项目 信息
GitHub 仓库 https://github.com/nginx-proxy/nginx-proxy
官方网站 https://github.com/nginx-proxy/nginx-proxy/tree/main/docs
开源协议 MIT
主要语言 Python(约 67.9%,配置生成脚本)
Star 数 约 20k
官方镜像 nginxproxy/nginx-proxy(Docker Hub)
内置 Nginx 1.31.6

nginx-proxy 会启动一个同时运行 nginx 与 docker-gen 的容器。docker-gen 监听 Docker 事件,根据容器的环境变量自动为 nginx 生成反向代理配置,并在容器启动 / 停止时自动 reload nginx。换句话说:你只要给被代理的容器加上一个 VIRTUAL_HOST=域名 环境变量,nginx-proxy 就会自动把对应域名的请求路由到这个容器,无需手写 nginx 配置。

该仓库目前由 ZeroSSL 官方维护,定位是“安全可靠的 SSL/TLS 解决方案”。

nginx-proxy 官方示意图

二、官方图片

上图为 nginx-proxy 官方 README 顶部的主题示意图(浅色主题)。它展示了通过环境变量驱动的自动化反向代理工作流。

三、环境要求

  • 已安装 Docker 引擎(推荐 20+),并具备 docker run 权限。
  • 服务器对外开放 80(HTTP)端口;若要 HTTPS 还需 443。
  • 被代理的容器必须满足两个条件(README 原文): 1. 通过 EXPOSE(Dockerfile)或 --expose(docker run)声明要被代理的端口; 2. 与 nginx-proxy 容器至少共享一个 Docker 网络。默认情况下,nginx-proxy 只接在默认 bridge 网络上,因此不在同一网络的容器它连不上。
  • DNS 需把你的域名(如 foo.bar.com)解析到运行 nginx-proxy 的宿主机 IP。

四、完整部署步骤

1. 启动 nginx-proxy 容器

官方 README 给出的启动命令(注意版本已固定为 1.11,而非 latest):

docker run --detach \
    --name nginx-proxy \
    --publish 80:80 \
    --volume /var/run/docker.sock:/tmp/docker.sock:ro \
    nginxproxy/nginx-proxy:1.11

参数说明:

  • --publish 80:80:把宿主机 80 端口映射到容器 80,对外接收 HTTP 请求。
  • --volume /var/run/docker.sock:/tmp/docker.sock:ro:只读挂载 Docker 套接字,这是 docker-gen 能监听容器事件、自动生成配置的前提。
  • nginxproxy/nginx-proxy:1.11:固定版本标签。

2. 启动一个要被代理的业务容器

接着启动任意你想代理的容器(这里以一个 nginx 容器为例),关键是带上环境变量 VIRTUAL_HOST:

docker run --detach \
    --name your-proxied-app \
    --env VIRTUAL_HOST=foo.bar.com \
    nginx

3. 验证自动路由

只要 DNS 已把 foo.bar.com 解析到运行 nginx-proxy 的宿主机,访问 http://foo.bar.com 时,请求就会被自动路由到那个 VIRTUAL_HOST 设为 foo.bar.com 的 your-proxied-app 容器。整个过程不需要手动写一行 nginx 配置。

# 查看 nginx-proxy 日志,应看到 docker-gen 检测到新容器并生成配置
docker logs -f nginx-proxy

4. 镜像版本选择

官方提供三种镜像变体:

  • Debian 版(默认):基于 nginx:mainline(Debian slim)。 shell docker pull nginxproxy/nginx-proxy:1.11
  • Alpine 版(-alpine 后缀):基于 nginx:alpine,体积更小。 shell docker pull nginxproxy/nginx-proxy:1.11-alpine
  • dockergen 版(-dockergen 后缀):用于“分离容器”方案,配合官方 nginx 镜像单独部署。 shell docker pull nginxproxy/nginx-proxy:1.11-dockergen

5. 关于版本标签的重要提醒

README 明确警告:不建议在生产环境使用 latest、alpine、dockergen 这三个浮动标签。它们指向 main 分支最新提交,不承诺稳定性,可能随时更新到不向后兼容的版本,导致你的代理配置意外中断。生产环境务必显式固定版本号(如 1.11)。

五、使用方法

  • 按域名路由:给每个业务容器设置 VIRTUAL_HOST=子域名.你的域名.com;一个容器也可用逗号写多个域名。
  • 指定后端端口:被代理容器必须 EXPOSE 正确端口。注意 README 说明:VIRTUAL_HOST 里不支持直接写端口号,要指定端口请使用 VIRTUAL_PORT 或参考文档中的 virtual ports / custom external HTTP/HTTPS ports 说明。
  • 共享网络:若业务容器使用自定义网络(--net mynet),请把 nginx-proxy 也加入同一网络,否则它无法连接后端。
  • 加 HTTPS:把证书以 域名.crt / 域名.key 命名挂载到 nginx-proxy 的 /etc/nginx/certs 目录,它会自动为对应域名启用 443 并自动跳转 HTTPS。
  • 更多配置:自定义模板、最大上传体积、Basic Auth 等见官方 docs 目录(README 指向 https://github.com/nginx-proxy/nginx-proxy/tree/main/docs)。

六、常见问题 FAQ

  1. 访问域名后访问的不是我的容器,而是默认页 / 503? 最常见原因是被代理容器没有 EXPOSE 正确端口,或与 nginx-proxy 不在同一 Docker 网络。按 README 的两个条件逐一核对。

  2. VIRTUAL_HOST=foo.bar.com:8080 这样写端口有效吗? 无效。README 明确 VIRTUAL_HOST 不支持在域名里写端口号。请用 VIRTUAL_PORT 环境变量或参考文档中的 virtual ports 方案。

  3. 为什么我用了 nginxproxy/nginx-proxy(不带版本号)后配置突然坏了? 因为不带版本号等于用 latest,它跟随 main 分支滚动。README 强烈建议生产固定版本(如 :1.11),升级时显式指定新版本。

  4. nginx-proxy 是怎么“自动”生成配置的? 它内部的 docker-gen 读取你挂载的 /var/run/docker.sock,监听容器创建/销毁事件,读取每个容器的 VIRTUAL_HOST 等环境变量,渲染 nginx 配置模板并 reload nginx。所以必须挂载 docker.sock。

  5. 被代理容器和 nginx-proxy 不在一个网络就连不上? 是。README 指出默认 nginx-proxy 只在默认 bridge 网络。自定义网络里的业务容器需要让 nginx-proxy 加入同一网络(--network)才能互通。

  6. HTTPS 怎么开? 将证书文件按 域名.crt 与 域名.key 命名挂载到 nginx-proxy 的 /etc/nginx/certs,重启容器后会自动为该域名启用 HTTPS。

七、跳转链接

评论交流

文章目录