PlantUML 自部署:从 plantuml.jar 到 Docker 到企业内网
当 plantuml.com 在线服务因为网络抖动/安全策略不可用时,可以自部署 PlantUML 渲染服务。这篇整理三种方案:本地 jar、Docker、企业自建。
三种部署方式
| 方案 |
适用 |
启动时长 |
plantuml.jar 本地 |
偶尔用、CI 临时 |
<2s |
| Docker 镜像 |
团队共享/CI 长期 |
<5s |
| plantuml-server 微服务 |
编辑器集成 / 服务调用 |
<10s |
方案 1:plantuml.jar 本地
最简单,一次性下载一个 jar 文件就能用:
1 2 3 4 5 6 7 8 9 10 11
| curl -L -o plantuml.jar https://github.com/plantuml/plantuml/releases/download/v1.2026.7/plantuml-1.2026.7.jar
java -jar plantuml.jar diagram.puml
java -jar plantuml.jar -tsvg diagram.puml
java -jar plantuml.jar -tsvg -failfast2 -nometadata docs/**/*.puml
|
优点
- 0 配置,0 依赖(除了 Java)
- 可以放进 Docker 镜像里
- CI 直接调用
缺点
- 启动慢(Java 冷启动 ~ 10s)
- 不支持 HTTP API,需要 CLI
- 1 个 jar 只能跑 1 件事
CI 集成
1 2 3 4 5
| - name: Render PlantUML run: | curl -L -o plantuml.jar https://github.com/plantuml/plantuml/releases/latest/download/plantuml.jar java -jar plantuml.jar -tsvg -nometadata -o rendered/ source/**/*.puml
|
方案 2:Docker 镜像
最常见,最稳,团队可以共享:
1 2 3 4
| docker run -d \ --name plantuml-server \ -p 8080:8080 \ plantuml/plantuml-server:latest
|
启动后访问 http://localhost:8080/,Web UI 自动展示。
API 端点
1 2 3
| GET http://localhost:8080/svg/<encoded> # 同步 SVG POST http://localhost:8080/form # 表单上传 GET http://localhost:8080/png/<encoded> # 同步 PNG
|
例子:
1 2
| curl http://localhost:8080/svg/SoWkIImgAStDuKh9IArEB-tWmyoStDpKiCLCmKeoZDGm7mwU5XH4e1NLWfG6S3U3AYXvDQG7WQpyLOqpCgN94fXAvuYAcd4oC8j4aIWfWGfGQUa_AvBlLf-4Ld4QbvWAm0
|
镜像 tag
1 2 3 4 5 6 7 8
| docker run plantuml/plantuml-server:latest
docker run plantuml/plantuml-server:v1.2026.7
docker run plantuml/plantuml-server:jdk17
|
性能调优
1 2 3 4 5 6 7
| docker run -d \ --name plantuml \ -p 8080:8080 \ -e PLANTUML_LIMIT_SIZE=4096 \ -e MAX_URL_LENGTH=4096 \ -e PLANTUML_SECURITY_PROFILE=INTERNET \ plantuml/plantuml-server:latest
|
-e 参数:
| Env var |
用途 |
PLANTUML_LIMIT_SIZE |
限制请求 URL 长度 |
MAX_URL_LENGTH |
URL 字节数 |
PLANTUML_SECURITY_PROFILE |
安全策略 |
JAVA_OPTS |
调整 JVM |
优点
- 团队共享一个统一版本
- HTTP API 容易集成
- 镜像轻量 ~ 100MB
缺点
- 默认 CORS 只允许同源
- 容器在 K8s 里存活期管理需要 Readiness
- 镜像更新要 restart
方案 3:Kubernetes 部署
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| apiVersion: apps/v1 kind: Deployment metadata: name: plantuml spec: replicas: 2 selector: matchLabels: app: plantuml template: metadata: labels: app: plantuml spec: containers: - name: plantuml image: plantuml/plantuml-server:latest ports: - containerPort: 8080 livenessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 30 readinessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 10 resources: requests: memory: "256Mi" cpu: "100m" limits: memory: "512Mi" cpu: "500m" --- apiVersion: v1 kind: Service metadata: name: plantuml spec: selector: app: plantuml ports: - port: 80 targetPort: 8080
|
Ingress + CORS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: plantuml annotations: nginx.ingress.kubernetes.io/cors-allow-origin: "https://puml.online" nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST" spec: rules: - host: plantuml.puml.online http: paths: - path: / pathType: Prefix backend: service: name: plantuml port: number: 80
|
只允许自己域名 puml.online 的页面访问。
集成编辑器
VS Code
1 2 3 4 5
| { "plantuml.server": "https://plantuml.puml.online", "plantuml.render": "PlantUMLServer" }
|
装 PlantUML 扩展,把 server URL 指向自部署实例。
Vim / Neovim
1 2 3
| let g:plantuml_server = 'https://plantuml.puml.online' let g:plantuml_render = 'plantuml-server'
|
装 vim-plantuml 插件。
IntelliJ IDEA
装 PlantUML Integration 插件:
1 2
| Settings → Plugins → PlantUML integration Set PlantUML server URL to https://plantuml.puml.online
|
CI / 编辑器共享
1 2 3
| Local editor ──→ https://plantuml.puml.online ──→ K8s Deployment │ └─→ CI (GitHub Actions)
|
单一服务,所有工具走同一 URL:
- 编辑器开发时拉取的预览
- CI 文档渲染
- 团队 wiki 静态嵌入
自部署的完整工作流
1 2 3 4 5 6 7 8 9 10 11 12 13
| +----------------------------------------------------------------+ | | | +-----+ +--------------------------------+ | | | Editor → | plantuml.puml.online | | | +-----+ | (K8s Service + CORS Ingress) | | | +-----+ | ↓ | | | | CI | → | +----------------------+ | | | +-----+ | | Deployment: 2 pods | | | | +-----+ | | image: plantuml/ | | | | | Wiki | → | | plantuml-server | | | | +-----+ | +----------------------+ | | | +--------------------------------+ | +----------------------------------------------------------------+
|
监控 / 日志
1 2 3
| - name: PLANTUML_METRICS value: "true"
|
暴露 Prometheus 指标:
1 2 3
| plantuml_render_total_diagrams plantuml_render_time_seconds plantuml_render_errors_total
|
日志:
1
| docker logs -f plantuml-server
|
输出请求 URL、状态、耗时。
升级流程
1 2 3 4 5 6 7 8
| docker pull plantuml/plantuml-server:latest
kubectl rollout restart deployment/plantuml
curl http://plantuml.puml.online/svg/SoWkIImgAStDuNc9LMqDBiLImiBeTWbG
|
K8s 滚动重启无宕机。
数据备份 / 状态
PlantUML server 是无状态服务,pod 重建不影响数据。
如果要做离线模式(断网用),镜像里就把 font 包好:
1 2
| FROM plantuml/plantuml-server:latest RUN apt-get install -y fonts-noto-cjk
|
常见配置陷阱
1. CORS 报错
1
| Access to fetch at 'https://plantuml...' from origin 'https://editor...' has been blocked by CORS
|
要修:
- 容器上加
PLANTUML_SECURITY_PROFILE=INTERNET
- 或者 Ingress/反向代理层加 CORS headers
2. URL 长度限制
默认 MAX_URL_LENGTH 是 4096 字节,复杂图可能超:
或者改用 POST 提交 form。
3. Java 内存溢出
大型图可能 OOM。给容器多一点内存:
1 2 3
| resources: limits: memory: "1Gi"
|
JVM:
4. 中文字体
默认 OpenJDK 字体,CJK 显示成方块。镜像里:
1
| RUN apt-get update && apt-get install -y fonts-noto-cjk
|
然后容器自带字体。
| 维度 |
自部署 |
plantuml.com |
| 网络依赖 |
内部网络 |
外网 |
| 性能 |
内网微秒级 |
受公网抖动影响 |
| 数据隐私 |
完全私有 |
提交到第三方 |
| 稳定性 |
自己控制 SLA |
看第三方故障 |
| 版本锁定 |
自己决定 |
跟随官方 |
| 维护成本 |
1 个 K8s 服务 |
0 |
一句话总结
自部署 PlantUML server 是 CI/CD/编辑器/团队 wiki 的「渲染层公共底座」。镜像标准化、K8s 自动扩缩,企业内网 + CORS 配置 + 字体支持三件套到位,就能跑生产。