Developer Tools AWS

PlantUML Server Diagram-as-Code Rendering on AWS User Guide

| Product: PlantUML Server - Secure Diagram-as-Code Rendering AMI by cloudimg

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.service systemd unit running the server bound to the loopback interface only, restarted automatically on failure

  • plantuml-firstboot.service systemd 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 /healthz for load balancer probes; port 80 serves the same health endpoint and redirects everything else to HTTPS

  • The INTERNET renderer security profile, blocking local-file includes and internal/loopback network fetches (SSRF hardening)

  • A dedicated EBS data volume mounted at /var/lib/plantuml for 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

  1. Open the listing in the AWS Marketplace and choose Continue to Subscribe, then Continue to Configuration and Continue to Launch.
  2. Select your instance type, VPC, subnet, key pair and a Security Group allowing inbound ports 22, 80 and 443.
  3. 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.

The PlantUML Server browser editor showing a sequence diagram source rendering live as a User Authentication Flow diagram with an actor, a Web App, an Auth Service and a User DB, and a View as PNG SVG ASCII PDF selector

Step 10: Render other diagram types

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

The PlantUML Server editor rendering a class diagram titled Order Domain Model, showing a Customer class with attributes and methods and its relationships to Order, LineItem and Product classes

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:

The PlantUML Server editor header Create your PlantUML diagrams directly in your browser, the encoded rendering-API URL in the address bar, and an activity diagram source describing a diagram-as-code rendering 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 below INTERNET.
  • 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/plantuml with 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.