PlantUML Server Diagram-as-Code Rendering on AWS User Guide
Overview
This guide covers deploying and using PlantUML Server on AWS from the cloudimg AWS Marketplace AMI. PlantUML Server is a browser-based rendering server for PlantUML, the popular open source diagram-as-code language. You type or paste plain-text diagram source into the editor and it renders live as a UML diagram, sequence, class, activity, state, component, use-case, deployment and more, which you can export as SVG, PNG or ASCII. It also exposes a stateless HTTP rendering API: an encoded diagram in the URL returns the rendered image, so wikis, documentation sites and editors can embed always-current diagrams generated straight from text in source control. PlantUML Server is released under the GPL-3.0 licence.
PlantUML Server ships with no built-in authentication of its own, so this image never exposes it directly. The server is bound to loopback only (127.0.0.1:8080) and fronted by nginx on port 443 over HTTPS with HTTP Basic Auth, so the renderer is never reachable without a credential. At first boot, plantuml-firstboot.service generates a unique per-instance Basic Auth password and a per-instance self-signed TLS certificate (there is no default login baked into the image), reloads nginx, proves an authenticated render round-trip, and writes the password to /root/plantuml-server-credentials.txt (mode 0600, root only). The renderer additionally runs with the INTERNET security profile, which blocks local-file includes and requests to internal or loopback network addresses, so it cannot be abused to reach instance metadata or internal services.
What is included:
-
PlantUML Server v1.2026.6, run from the maintainer's official pinned distribution (digest-verified), which bundles the diagram engine and Graphviz so class, activity, state and component diagrams render without any extra setup
-
plantuml.servicesystemd unit running the server bound to the loopback interface only, restarted automatically on failure -
plantuml-firstboot.servicesystemd oneshot that generates the per-instance HTTP Basic Auth password and TLS certificate, reloads nginx, proves an authenticated render round-trip and writes/root/plantuml-server-credentials.txt -
nginx on port 443 (HTTPS) reverse proxying to the loopback-bound PlantUML listener, with HTTP Basic Auth and an unauthenticated
/healthzfor load balancer probes; port 80 serves the same health endpoint and redirects everything else to HTTPS -
The
INTERNETrenderer security profile, blocking local-file includes and internal/loopback network fetches (SSRF hardening) -
A dedicated EBS data volume mounted at
/var/lib/plantumlfor the appliance's container store and logs, independently resizable from the OS disk -
Ubuntu 24.04 LTS base with the latest security patches
-
24/7 cloudimg support with a guaranteed 24-hour response SLA
Connecting to your instance
Connect over SSH on port 22 as the default login user for your AMI variant, using the EC2 key pair you selected at launch:
| AMI variant | SSH login user |
|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i /path/to/your-key.pem ubuntu@<vm-ip>
Prerequisites
- An AWS account subscribed to this listing
- An EC2 key pair for SSH access
- A Security Group allowing inbound TCP 22 (SSH), TCP 80 and TCP 443 (the web editor and rendering API) from your address
- The recommended instance type is m5.large; larger instances render bigger diagrams faster
Step 1: Launch from the AWS Console
- Open the listing in the AWS Marketplace and choose Continue to Subscribe, then Continue to Configuration and Continue to Launch.
- Select your instance type, VPC, subnet, key pair and a Security Group allowing inbound ports 22, 80 and 443.
- Launch, and wait a minute or two for the first boot to generate the per-instance credential and certificate.
Step 2: Launch from the AWS CLI
aws ec2 run-instances \
--image-id <ami-id-from-listing> \
--instance-type m5.large \
--key-name your-key \
--security-group-ids sg-xxxxxxxx \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=plantuml-server}]'
Step 3: Verify the services are running
PlantUML Server runs from a pinned container supervised by systemd, behind nginx. All three services should be active:
systemctl is-active docker plantuml nginx
active
active
active
Step 4: Inspect the runtime and listeners
The PlantUML container publishes only to the loopback interface on port 8080; only nginx (ports 80 and 443) is exposed to the network:
sudo docker ps --format '{{.Image}} {{.Status}} {{.Ports}}'
sudo ss -Htlnp | awk '{print $4}' | sort -u
5b9968b8723e Up 8 minutes 127.0.0.1:8080->8080/tcp
0.0.0.0:443
0.0.0.0:80
127.0.0.1:8080
The renderer also runs with the INTERNET security profile (SSRF and local-include hardening):
sudo docker inspect plantuml --format '{{range .Config.Env}}{{println .}}{{end}}' | grep SECURITY
PLANTUML_SECURITY_PROFILE=INTERNET
Step 5: Confirm the dedicated data volume
The appliance's container store and logs live on a dedicated EBS volume mounted at /var/lib/plantuml:
mountpoint /var/lib/plantuml && df -h /var/lib/plantuml | tail -1
Step 6: Retrieve the access password
At first boot the image generates a unique HTTP Basic Auth password and writes it, root-only, to /root/plantuml-server-credentials.txt:
sudo cat /root/plantuml-server-credentials.txt
PLANTUML_HTTP_USER=admin
PLANTUML_BASIC_AUTH_PASSWORD=<PLANTUML_BASIC_AUTH_PASSWORD>
PLANTUML_URL=https://<instance-public-ip>/
PLANTUML_HEALTHZ=https://<instance-public-ip>/healthz
The username is admin. Keep this password safe; it is unique to this instance.
Step 7: Verify access control over HTTPS
An unauthenticated request is rejected, and the unauthenticated health endpoint is available for load-balancer probes:
curl -sk -o /dev/null -w 'unauthenticated: HTTP %{http_code}\n' https://localhost/
curl -sk -o /dev/null -w 'healthz: HTTP %{http_code}\n' https://localhost/healthz
unauthenticated: HTTP 401
healthz: HTTP 200
Step 8: Render a diagram from the command line
The stateless rendering API takes an encoded diagram in the URL and returns the image. The image ships a small helper, plantuml-encode, that produces the encoded form:
PW=$(sudo grep '^PLANTUML_BASIC_AUTH_PASSWORD=' /root/plantuml-server-credentials.txt | cut -d= -f2-)
ENC=$(printf '@startuml\nAlice -> Bob: Hello\nBob --> Alice: Hi\n@enduml' | /usr/local/bin/plantuml-encode)
curl -sk -o /dev/null -w 'SVG render: HTTP %{http_code}\n' -u "admin:$PW" "https://localhost/svg/$ENC"
SVG render: HTTP 200
Step 9: Open the editor in a browser
Open https://<instance-public-ip>/ in your browser, accept the per-instance self-signed certificate, and sign in with username admin and the password from Step 6. Type PlantUML source on the left and the diagram renders live, with one-click export to PNG, SVG, ASCII or PDF.

Step 10: Render other diagram types
PlantUML supports many diagram types. A class diagram is laid out by the bundled Graphviz engine:

Step 11: Embed diagrams with the rendering API
Because rendering is a stateless URL, you can embed always-current diagrams anywhere by pointing at https://<instance>/svg/<encoded> or /png/<encoded>. The editor's address bar shows the encoded URL for the current diagram, which you can copy straight into a wiki, README or documentation pipeline:

Step 12: Managing the service
# Status and logs
systemctl status plantuml nginx
sudo docker logs plantuml
# Restart the renderer or the proxy
sudo systemctl restart plantuml
sudo systemctl restart nginx
To rotate the web password, edit /etc/nginx/.plantuml_htpasswd with sudo htpasswd -B /etc/nginx/.plantuml_htpasswd admin, then sudo systemctl reload nginx.
Step 13: Security recommendations
- Restrict the Security Group to the addresses that need the editor and API; keep SSH (22) limited to your admin network.
- Use your own domain and certificate: the per-instance certificate is self-signed. For production, terminate TLS at nginx with a certificate from your CA or AWS Certificate Manager via a load balancer.
- Keep the
INTERNET(or stricter) security profile. It blocks local-file includes and internal-address fetches. Do not lower it belowINTERNET. - Do not expose the loopback port. The renderer must stay bound to 127.0.0.1:8080; only nginx should face the network.
- Snapshot the data volume at
/var/lib/plantumlwith AWS Backup as part of your routine. - Patch regularly with
sudo apt update && sudo apt upgrade, and pull a newer pinned server image when you update.
Step 14: Support and licensing
PlantUML Server is licensed under the GPL-3.0 licence. This cloudimg image packages the upstream software with security hardening and a per-instance credential; the software charge on this listing is for cloudimg support services in addition to standard AWS infrastructure costs.
Need Help?
cloudimg provides 24/7 technical support by email and live chat at support@cloudimg.co.uk. We help with deployment, reverse-proxy and certificate setup, wiring the rendering API into your tools, renderer tuning, instance sizing, patching guidance and EBS volume management.