PlantUML for Confluence
Documentation · v1
A Confluence Cloud Forge app that renders PlantUML diagrams inline on pages. Works out of the box using the public plantuml.com renderer. For sensitive diagrams, a site admin can point it at any PlantUML server they control (BYOS).
Quickstart
- Install the app from the Atlassian Marketplace.
- Edit any page and insert the PlantUML macro — type
/PlantUMLin the slash menu or pick it from the macro browser. - Paste your PlantUML source into the config panel:
@startuml
Alice -> Bob: hello
Bob --> Alice: hi
@enduml
- Publish the page. The diagram renders as an inline SVG.
No configuration required — the macro uses the public plantuml.com server by default. For sensitive diagrams, follow the BYOS setup below.
BYOS — bring your own server
A Confluence site admin can change the global render server URL in Confluence settings → Apps → PlantUML. Every diagram on the site then renders through your own server instead of plantuml.com.
1. Run the PlantUML server
docker run -d --name plantuml-server \
-p 8080:8080 plantuml/plantuml-server:tomcat
Verify it's up: visit http://your-host:8080/ and you should see the PlantUML demo page.
2. Put it behind HTTPS
Confluence Cloud is served over HTTPS, so the render server must be HTTPS too — browsers block mixed content. Terminate TLS at a reverse proxy in front of the Tomcat container.
Minimal nginx example:
server {
listen 443 ssl http2;
server_name plantuml.example.com;
ssl_certificate /etc/letsencrypt/live/plantuml.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/plantuml.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
3. The CORS double-header gotcha
This is the #1 BYOS setup failure. Read this before you configure a proxy.
The PlantUML Tomcat server already sets Access-Control-Allow-Origin: * on every response. If your reverse proxy also adds this header, browsers reject the response as invalid (duplicate CORS headers), and diagrams silently fail to load.
Fix A — let Tomcat keep its header; make the proxy not add one. For nginx: remove any add_header 'Access-Control-Allow-Origin' '*' from the proxy block. For Caddy/Traefik: remove any CORS middleware.
Fix B — make Tomcat stop emitting the header; let the proxy own it. Mount a setenv.sh into the container:
JAVA_OPTS="$JAVA_OPTS \
-DPLANTUML_CORS_ALLOWED_ORIGIN=https://your-site.atlassian.net"
Then have the reverse proxy set Access-Control-Allow-Origin. Either way, exactly one layer should emit the header. Verify:
curl -sI https://plantuml.example.com/svg/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000 \
| grep -i access-control-allow-origin
You should see exactly one Access-Control-Allow-Origin line in the output.
4. Configure the app
In Confluence settings → Apps → PlantUML, set the PlantUML server URL to your HTTPS endpoint (e.g. https://plantuml.example.com) and save. New page renders use your server immediately — no reinstall needed.
How it works
Each diagram's PlantUML source is stored in the macro's config, inside the page's ADF — so it travels with copy/paste and page exports like any other page content.
Rendering is entirely client-side: the macro's React component composes serverUrl + "/svg/" + encodedSource and uses it as an image source. No Forge function makes an HTTP request to the render server. This is why the manifest requests external.images: [{ address: "*" }] with a wildcard — each install picks its own server URL, so a static allowlist is architecturally impossible.
Privacy
Palori collects nothing. The app stores only one value per site (the render server URL) in Atlassian's Forge KVS (storage:app scope). Diagram source lives inside the macro on the page.
When using the default plantuml.com server, your diagram source is sent to plantuml.com at view time. That server is operated by the PlantUML project, not by Palori. If that's not acceptable for your data, use BYOS.
See the privacy policy for the full disclosure.
Source code
Source-available at github.com/paloriapps/plantuml-confluence under the PolyForm Shield 1.0.0 license. You can read, audit, self-host, and modify the code. You cannot republish it as a competing Marketplace listing.