nginx-proxy:近两万 Star 的 Docker 自动化反向代理方案

nginx-proxy 是一个在 GitHub 上获得近 2 万 Star 的开源工具,专门解决 Docker 容器的反向代理配置自动化问题。对于在单台或少量主机上运行多个容器化服务的场景,手动维护 nginx 配置是一件重复且容易出错的工作。

正文顶部截图

README区域截图

这个工具的核心思路是把 nginx 和 docker-gen 打包在一个容器里运行。docker-gen 会监听 Docker 的容器事件,当有新容器启动或现有容器停止时,它会读取容器的元数据,自动生成对应的 nginx 反向代理配置文件,然后向 nginx 发送 reload 信号。配置变更在秒级生效,整个过程不需要人工介入,也不需要手动编写和维护 nginx 配置文件。

使用 nginx-proxy 的步骤很直接。首先启动 nginx-proxy 容器,需要把主机的 Docker socket 以只读方式挂载到容器内部,这样 docker-gen 才能读取其他容器的信息:

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

然后启动需要被代理的应用容器,添加 VIRTUAL_HOST 环境变量指定域名即可:

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

当 DNS 把域名解析到运行 nginx-proxy 的主机后,访问请求就会被自动路由到设置了对应 VIRTUAL_HOST 的容器。新增服务只需要启动容器并设置环境变量,下线服务直接停止容器,代理配置会同步更新。

被代理的容器需要满足两个条件。一是通过 Dockerfile 的 EXPOSE 指令或 docker run 的 --expose 参数暴露需要代理的端口。二是必须与 nginx-proxy 容器共享至少一个 Docker 网络。默认情况下 nginx-proxy 只连接 bridge 网络,如果应用容器在其他自定义网络中运行,代理将无法连接,启动应用容器时需要显式指定相同的网络。

项目提供两种镜像版本。Debian 版本基于 nginx:mainline 构建,兼容性较好,适合大多数常规场景。Alpine 版本基于 nginx:alpine,镜像体积更小,启动更快,通过镜像名加 -alpine 后缀获取。官方明确建议生产环境使用带具体版本号的标签,比如 1.11 或 1.11-alpine,不要使用 latest 或 alpine 标签。因为这些标签始终指向主分支的最新提交,不保证向后兼容,可能在镜像更新时引入配置语法或服务行为的变更。

这个方案特别适合开发环境和中小型部署场景。在本地开发时,可以快速为多个服务分配独立域名,避免记忆各种端口号,配合本地 DNS 或 hosts 文件即可实现接近生产环境的访问方式。在小型生产环境中,它提供了一种轻量级的服务发现机制,不需要引入完整的容器编排平台就能实现基本的负载均衡和请求分发。

这个项目目前由 ZeroSSL 官方团队维护,作为其 SSL 和 TLS 解决方案生态的一部分。

roSSL 官方团队维护,作为其 SSL 和 TLS 解决方案生态的一部分。

更多推荐