ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Dokku Haproxy 代理插件实战指南:基于 EasyHaproxy 的 Docker 标签路由、SSL 与运维全解析

2026/9/11 12:48:53 拓冰建站 浏览量
Dokku Haproxy 代理插件实战指南:基于 EasyHaproxy 的 Docker 标签路由、SSL 与运维全解析 Dokku Haproxy 代理插件实战指南基于 EasyHaproxy 的 Docker 标签路由、SSL 与运维全解析【免费下载链接】dokkuA docker-powered PaaS that helps you build and manage the lifecycle of applications项目地址: https://gitcode.com/GitHub_Trending/do/dokkuHaproxy 代理插件是 Dokku自 0.28.0 起提供中基于 Docker 标签label机制的轻量级反向代理方案通过 EasyHaproxy 实现对容器流量的自动发现与路由。本文围绕 docs/networking/proxies/haproxy.md 展开完整讲解插件命令、切换流程、属性配置、标签管理、SSL/Lets Encrypt 集成及报告查看并深入plugins/haproxy-vhosts的源码实现与测试用例帮助你从安装、启停到排障全链路掌握该代理方案。插件概述与适用场景Dokku 官方默认代理实现是 nginxnginx-vhosts而 Haproxy 插件则提供了另一条路由路径它不直接维护自己的配置文件而是利用 EasyHaproxy 实现的 Docker 标签集成——部署时由插件把路由规则以容器标签的形式注入容器EasyHaproxy 作为独立容器监听 Docker API动态生成 Haproxy 配置并完成请求转发。该集成在 Dokku 0.28.0 中引入其核心优势在于路由规则完全由容器标签驱动标签变化域、端口映射由 EasyHaproxy 自动感知无需像 nginx 方案那样在宿主机上管理虚拟主机配置。需要说明的是本仓库 plugins/haproxy-vhosts/Dockerfile 当前指定的镜像为byjg/easy-haproxy:6.1.1该文件通过FROM行定义了默认镜像报告输出中的 computed image 即由此解析而来。插件命令速查插件对外暴露以下命令也可通过dokku help查看完整说明haproxy:report [app] [flag] # Displays a haproxy report for one or more apps haproxy:logs [--num num] [--tail] # Display haproxy log output haproxy:set app property (value) # Set or clear an haproxy property for an app haproxy:show-config app # Display haproxy compose config haproxy:start # Starts the haproxy server haproxy:stop # Stops the haproxy server此外还有标签管理相关的子命令haproxy:labels:add、haproxy:labels:remove、haproxy:labels:show其实现位于 plugins/haproxy-vhosts/command-functions内部委托给 proxy 插件的通用标签函数cmd-proxy-labels-*只是代理类型固定为haproxy。环境要求使用 Haproxy 插件集成要求宿主机安装 Docker 的docker-compose-plugin。从源码实现看haproxy:start、haproxy:stop、haproxy:show-config三个命令在 plugins/haproxy-vhosts/command-functions 中都会先调用fn-is-compose-installed做前置校验未安装时直接报错 Required docker compose plugin is not installed。Docker 官方文档提供了该插件的安装说明请根据你的 Docker 安装方式发行版包管理器或 Docker 官方脚本选择对应的安装途径。路由规则与工作机制Haproxy 插件在路由上有几条明确的规则理解它们有助于避免部署后的“意外”标签驱动Haproxy 集成通过附加到容器上的 Docker 标签暴露。标签的变化需要应用重新部署deploy或重建rebuild才会生效。仅 web 进程注入标签Haproxy 会尊重其他容器上已存在的标签但插件只会为web类型的进程注入 Haproxy 标签。对应源码见 plugins/haproxy-vhosts/docker-args-process-deploy 开头的判断PROC_TYPE ! web时直接返回。端口映射限制目前仅支持http:80和https:443两种端口映射。源码中会遍历ports-get得到的端口映射挑选主机端口为 80/443 的映射作为候选若未找到 80 端口映射会输出 Warning: http:80 port mapping not found 并退而使用第一个 http 映射。健康检查通过即路由只要容器处于运行状态且通过健康检查请求就会被路由到该容器不存在 nginx 方案中的“维护中页面”等中间状态。标签注入的源码细节在 plugins/haproxy-vhosts/docker-args-process-deploy 中可以看到完整的标签生成逻辑插件会依次检查proxy-type是否为haproxy、proxy-is-enabled是否为true、domains-vhost-enabled是否启用随后将应用的域名列表来自domains-list多个域名以逗号拼接和端口映射组合成一组标签例如--label haproxy.app-web.localportcontainer_port --label haproxy.app-web.modehttp --label haproxy.app-web.port80 --label haproxy.app-web.hostcomma-separated-domains当存在 https 端口映射或启用了 Lets Encrypt 时还会注入redirect_ssltrue与一组-https后缀的标签如haproxy.app-web-https.letsencrypttrue、haproxy.app-web-https.port443否则注入redirect_sslfalse。用户自定义标签则从fn-proxy-get-labels-file-path haproxy $APP指定的标签文件中读取并追加到--label参数中。部署完成后plugins/haproxy-vhosts/core-post-deploy 会输出 Routing app via haproxy 的日志信息提示该应用已由 Haproxy 接管路由。切换到 Haproxy 代理[!WARNING] 在同一台 Dokku 主机上同时使用多个代理插件可能导致请求路由冲突应尽量避免。由于默认代理实现是 nginx切换到 Haproxy 前建议先停止 nginx 服务。针对某个应用切换到 Haproxy 使用proxy:set命令dokku proxy:set node-js-app type haproxy这会启用基于 Docker 标签的 Haproxy 集成之后所有部署都会注入 Haproxy 可读取的路由标签。由于标签机制的特性必须执行一次部署或重建请求才能成功路由dokku ps:rebuild node-js-app同样地修改域名domains或端口映射port mappings之后也需要重新部署或重建应用才会生效。启动与停止 Haproxy 容器Haproxy 本身运行在一个由 Docker Compose 管理的独立容器中启动与停止均由插件命令完成。启动dokku haproxy:start该命令内部见 plugins/haproxy-vhosts/command-functions 的cmd-haproxy-start会先把proxy-status属性写为started再基于模板生成 compose 文件并执行docker compose up。compose 模板位于 plugins/haproxy-vhosts/templates/compose.yml.sigil其服务配置要点如下镜像使用HAPROXY_IMAGE计算值默认来自插件 Dockerfile 的FROM行环境变量EASYHAPROXY_DISCOVERdocker通过 Docker API 发现容器、EASYHAPROXY_LABEL_PREFIXhaproxy只读取haproxy前缀的标签、EASYHAPROXY_LOG_LEVEL、EASYHAPROXY_REFRESH_CONF、CERTBOT_LOG_LEVEL与HAPROXY_LOG_LEVEL并关闭统计端口HAPROXY_STATS_PORTfalse网络与端口network_mode: bridge映射80:80仅当设置了HAPROXY_LETSENCRYPT_EMAIL时才映射443:443并注入EASYHAPROXY_LETSENCRYPT_EMAIL与EASYHAPROXY_LETSENCRYPT_SERVER持久化与自愈restart: unless-stopped并将宿主机的/var/run/docker.sock以只读方式挂载进容器——这是 EasyHaproxy 监听 Docker 事件/轮询标签变化的数据来源。停止dokku haproxy:stop对应cmd-haproxy-stop先把proxy-status写为stopped再执行docker compose down。容器会被停止并从系统中移除如果容器本来就没有运行该命令不会产生任何效果。查看 compose 配置调试时可用以下命令查看实际生成的 compose 配置即渲染后的模板内容dokku haproxy:show-config它同样要求 docker compose 插件已安装输出由模板渲染出的完整 compose 文件。属性Property配置插件所有属性均为全局属性global only只能通过dokku haproxy:set --global property value设置。校验逻辑见 plugins/haproxy-vhosts/subcommands/setGLOBAL_ONLY_KEYS包含全部五个属性对非--global作用域设置会直接报错 The key ... can only be set globally合法的属性键为image、log-level、letsencrypt-email、letsencrypt-server、refresh-conf。可设置属性的完整说明如下PropertyScopeDefaultReport flagsDescriptionimageglobal onlyparsed fromplugins/haproxy-vhosts/Dockerfile--haproxy-global-image,--haproxy-computed-imageDocker image used to run the Haproxy containerletsencrypt-emailglobal onlynone--haproxy-global-letsencrypt-email,--haproxy-computed-letsencrypt-emailContact email enabling letsencrypt; empty disables https issuanceletsencrypt-serverglobal onlyhttps://acme-v02.api.letsencrypt.org/directory--haproxy-global-letsencrypt-server,--haproxy-computed-letsencrypt-serverACME directory used when requesting certificateslog-levelglobal onlyERROR--haproxy-global-log-level,--haproxy-computed-log-levelHaproxy log levelrefresh-confglobal only10--haproxy-global-refresh-conf,--haproxy-computed-refresh-confSeconds between Haproxy polls of the Docker API for label changes从 plugins/haproxy-vhosts/internal-functions 的fn-haproxy-computed-*系列函数可以看出“global 原始值”与“computed 生效值”的关系computed 值在 global 值为空时回退到内置默认值如log-level默认ERROR且会转为大写refresh-conf默认10letsencrypt-server默认https://acme-v02.api.letsencrypt.org/directoryimage默认值则直接解析 plugins/haproxy-vhosts/Dockerfile 的FROM行。自定义容器镜像默认镜像虽然写死在插件中但可以通过--global标志的image属性覆盖dokku haproxy:set --global image byjg/easy-haproxy:4.0.0修改后需重启 Haproxy 容器dokku haproxy:stop dokku haproxy:start使其生效。查看容器日志需要确认 Haproxy 是否按预期运行时可查看其容器日志dokku haproxy:logs该命令支持以下修饰参数--num NUM # the number of lines to display --tail # continually stream logs组合使用示例dokku haproxy:logs --tail --num 10上述命令会持续流式输出日志并先显示最近 10 行历史。从实现看fn-haproxy-logsplugins/haproxy-vhosts/internal-functions实际执行的是docker logs haproxy-haproxy-1--tail对应--follow--num默认值为 100。顺带说明官方文档中“从 vector 容器输出日志”的描述对应的是其他代理插件如 Caddy/Traefik的日志链路本插件的日志对象是名为haproxy-haproxy-1的 compose 服务容器。修改日志级别Haproxy 日志输出默认级别为ERROR可通过--global标志的log-level属性修改dokku haproxy:set --global log-level DEBUG修改后需要重启 Haproxy 容器。修改刷新间隔EasyHaproxy 默认每10秒轮询一次 Docker API 以感知标签变化可通过refresh-conf属性调整全局唯一不能按应用设置dokku haproxy:set --global refresh-conf 5设置为空值会重置回默认值。修改后同样需要重启 Haproxy 容器。标签管理Label Management插件允许为应用添加自定义容器标签这些标签会在部署时注入容器用于配置插件默认行为之外的 Haproxy 特性。可用的标签集合请参阅上游 EasyHaproxy 文档。添加标签dokku haproxy:labels:add node-js-app haproxy.directive value该命令会为应用的容器添加标签haproxy.directivevalue。添加后需重建或重新部署应用标签才会应用到运行中的容器dokku ps:rebuild node-js-app移除标签dokku haproxy:labels:remove node-js-app haproxy.directive移除指定标签后同样需要重建或重新部署应用dokku ps:rebuild node-js-app查看标签查看应用的全部自定义容器标签dokku haproxy:labels:show node-js-app只查看某个标签的具体值则附加标签名dokku haproxy:labels:show node-js-app haproxy.directive从实现上看这三个命令plugins/haproxy-vhosts/command-functions分别映射到cmd-proxy-labels-add/cmd-proxy-labels-remove/cmd-proxy-labels-show标签持久化在插件各自的标签文件中docker-args-process-deploy触发器会在部署时逐行读取该文件并追加--label参数同时注意它会在自定义标签外再包一层单引号因此自定义标签值中应避免出现需要 shell 转义的字符。SSL 配置与 Lets Encrypt 集成Haproxy 插件只支持通过其内置的 Lets Encrypt 集成自动签发证书由certs插件提供的托管证书managed certificates会被忽略。启用 Lets Encrypt默认情况下 letsencrypt 处于禁用状态https 端口映射会被忽略。通过--global标志的letsencrypt-email属性启用dokku haproxy:set --global letsencrypt-email automateddokku.sh启用后需要重启 Haproxy 容器并重建应用让新标签生效。此后所有 http 请求都会被重定向到 https。从 compose 模板plugins/haproxy-vhosts/templates/compose.yml.sigil可见只有设置了EASYHAPROXY_LETSENCRYPT_EMAIL时容器才会映射443:443端口并注入 letsencrypt 相关环境变量这也是“未启用时不监听 443”的根本原因。自定义 Lets Encrypt 服务器letsencrypt 集成默认使用生产环境服务器。如需切换例如联调或压测时使用 staging 环境设置letsencrypt-server属性dokku haproxy:set --global letsencrypt-server https://acme-staging-v02.api.letsencrypt.org/directory修改后需要重启 Haproxy 容器并重建应用证书才会从新服务器签发。查看应用报告使用haproxy:report可以查看应用当前的 Haproxy 配置报告dokku haproxy:report输出示例 node-js-app haproxy information Haproxy computed image: byjg/easy-haproxy:4.0.0 Haproxy computed letsencrypt email: Haproxy computed letsencrypt server: https://acme-v02.api.letsencrypt.org/directory Haproxy computed log level: ERROR Haproxy computed refresh conf: 10 Haproxy global image: Haproxy global letsencrypt email: Haproxy global letsencrypt server: Haproxy global log level: Haproxy global refresh conf:其中global-prop键保存原始全局值未设置时为空computed-prop键保存部署时实际生效的值全局值为空时回退到内置默认值。报告也可以针对单个应用查看dokku haproxy:report node-js-app还支持传入 flag 只输出某一项的具体值dokku haproxy:report node-js-app --haproxy-computed-image报告功能的 Go 实现位于 plugins/haproxy-vhosts/report.goReportSingleApp与各report*函数入口分发在 plugins/haproxy-vhosts/src/subcommands/subcommands.go且支持--format stdout|json输出格式haproxy:report --global还可查看全局级别的报告。内部属性以下属性不由haproxy:set管理而是插件内部记录的状态PropertyDescriptionSourceproxy-statusstarted/stoppedstate of the haproxy compose projectcmd-haproxy-start/cmd-haproxy-stopinplugins/haproxy-vhosts/command-functions该属性的作用体现在 plugins/haproxy-vhosts/pre-restore当proxy-status为started时pre-restore触发器会在 Dokku 恢复如主机重启后的应用恢复流程时自动调用cmd-haproxy-start重新拉起 Haproxy 容器若启动失败会输出警告 Failed to restore haproxy proxy, requests may not route as expected。测试与验证仓库中 tests/unit/haproxy-vhosts.bats 与 tests/unit/haproxy.bats 覆盖了该插件的核心行为如属性设置、报告输出、compose 模板渲染等tests/unit/report.bats 则覆盖报告命令的多种 flag 组合。在自行修改或排查插件问题时可以参考这些 Bats 用例了解预期的命令输出格式与属性回退行为。常见问题与最佳实践切换后请求 404 / 路由不生效绝大多数情况是因为切换代理类型、修改域名或端口映射后未执行部署或重建。记得运行dokku ps:rebuild app。443 端口未监听确认是否已设置letsencrypt-email——未设置时 compose 模板不会映射 443 端口https 端口映射会被忽略。修改属性后不生效image、log-level、letsencrypt-*、refresh-conf均为全局属性且作用于 Haproxy 容器本身修改后必须dokku haproxy:stop dokku haproxy:start或haproxy:start自动拉起重启容器。不要混用多个代理插件同机多代理会导致请求路由冲突切换前先停掉 nginx 服务。观察 EasyHaproxy 动态行为若标签变化未按预期生效用dokku haproxy:logs --tail观察容器日志并可通过dokku haproxy:show-config确认生成的 compose 配置是否符合预期。通过上述命令与配置你可以在 Dokku 上完整落地一套基于 Haproxy/EasyHaproxy 的容器路由方案并借助 Docker 标签机制灵活扩展其路由与 TLS 行为。【免费下载链接】dokkuA docker-powered PaaS that helps you build and manage the lifecycle of applications项目地址: https://gitcode.com/GitHub_Trending/do/dokku创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考