doc/administration/integration/plantuml.md
{{< details >}}
{{< /details >}}
Use the PlantUML integration, to create diagrams in snippets, wikis, and repositories. GitLab.com integrates with PlantUML for all users, and requires no additional configuration.
To set up the integration on your GitLab Self-Managed instance, you must configure your PlantUML server.
After completing the integration, PlantUML converts plantuml
blocks to an HTML image tag, with the source pointing to the PlantUML instance. The PlantUML
diagram delimiters @startuml/@enduml aren't required because they are replaced
by the plantuml block:
Markdown files with the extension .md:
```plantuml
Bob -> Alice : hello
Alice -> Bob : hi
```
For additional acceptable extensions, review the
languages.yaml file.
AsciiDoc files with the extension .asciidoc, .adoc, or .asc:
[plantuml, format="png", id="myDiagram", width="200px"]
----
Bob->Alice : hello
Alice -> Bob : hi
----
reStructuredText:
.. plantuml::
:caption: Caption with **bold** and *italic*
Bob -> Alice: hello
Alice -> Bob: hi
Although you can use the uml:: directive for compatibility with
sphinxcontrib-plantuml,
GitLab supports only the caption option.
If the PlantUML server is configured correctly, these examples should render a diagram instead of the code block:
Bob -> Alice : hello
Alice -> Bob : hi
Inside blocks, add any of the diagrams PlantUML supports, such as:
Add parameters to block definitions:
id: A CSS ID added to the diagram HTML tag.width: Width attribute added to the image tag.height: Height attribute added to the image tag.Markdown does not support any parameters, and always uses PNG format.
To include or embed a PlantUML diagram from separate files in the repository, use
the include directive. Use this to maintain complex diagrams in dedicated files, or to
reuse diagrams. For example:
Markdown:
```plantuml
::include{file=diagram.puml}
```
AsciiDoc:
[plantuml, format="png", id="myDiagram", width="200px"]
----
include::diagram.puml[]
----
[!note] The
::includedirective resolves only after the file is committed to the repository. The Markdown editor preview does not render included files. To verify the diagram renders correctly, commit the file and view it in the repository file browser.
Before you can enable PlantUML in GitLab, set up your own PlantUML server to generate the diagrams:
To run a PlantUML container in Docker, run this command:
docker run -d --name plantuml -p 8005:8080 plantuml/plantuml-server:tomcat
The PlantUML URL is the hostname of the server running the container.
When running GitLab in Docker, it must have access to the PlantUML container.
To achieve that, use Docker Compose.
In this basic docker-compose.yml file, PlantUML is accessible to GitLab at the URL
http://plantuml:8080/:
services:
gitlab:
image: 'gitlab/gitlab-ee:18.9.1-ee.0'
environment:
GITLAB_OMNIBUS_CONFIG: |
nginx['custom_gitlab_server_config'] = "location /-/plantuml/ { \n rewrite ^/-/plantuml/(.*) /$1 break;\n proxy_cache off; \n proxy_pass http://plantuml:8080/; \n}\n"
plantuml:
image: 'plantuml/plantuml-server:tomcat'
container_name: plantuml
ports:
- "8005:8080"
Next, you can:
You can install and configure a PlantUML server in Debian/Ubuntu distributions using Tomcat or Jetty. The instructions below are for Tomcat.
Prerequisites:
PlantUML recommends to install Tomcat 10.1 or later. The scope of this page only includes setting up a basic Tomcat server. For more production-ready configurations, see the Tomcat documentation.
Install JDK/JRE 11:
sudo apt update
sudo apt install default-jre-headless graphviz git
Add a user for Tomcat:
sudo useradd -m -d /opt/tomcat -U -s /bin/false tomcat
Install and configure Tomcat 10.1:
wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.33/bin/apache-tomcat-10.1.33.tar.gz -P /tmp
sudo tar xzvf /tmp/apache-tomcat-10*tar.gz -C /opt/tomcat --strip-components=1
sudo chown -R tomcat:tomcat /opt/tomcat/
sudo chmod -R u+x /opt/tomcat/bin
Create a systemd service. Edit the /etc/systemd/system/tomcat.service file and add:
[Unit]
Description=Tomcat
After=network.target
[Service]
Type=forking
User=tomcat
Group=tomcat
Environment="JAVA_HOME=/usr/lib/jvm/java-1.11.0-openjdk-amd64"
Environment="JAVA_OPTS=-Djava.security.egd=file:///dev/urandom"
Environment="CATALINA_BASE=/opt/tomcat"
Environment="CATALINA_HOME=/opt/tomcat"
Environment="CATALINA_PID=/opt/tomcat/temp/tomcat.pid"
Environment="CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC"
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
RestartSec=10
Restart=always
[Install]
WantedBy=multi-user.target
JAVA_HOME should be the same path as seen in sudo update-java-alternatives -l.
To configure ports, edit your /opt/tomcat/conf/server.xml and choose your
ports. Recommended:
8005 to 80068005 for the Tomcat HTTP endpoint. The default port 8080 should be avoided,
because Puma listens on port 8080 for metrics.- <Server port="8006" shutdown="SHUTDOWN">
+ <Server port="8005" shutdown="SHUTDOWN">
- <Connector port="8005" protocol="HTTP/1.1"
+ <Connector port="8080" protocol="HTTP/1.1"
Reload and start Tomcat:
sudo systemctl daemon-reload
sudo systemctl start tomcat
sudo systemctl status tomcat
sudo systemctl enable tomcat
The Java process should be listening on these ports:
root@gitlab-omnibus:/plantuml-server# ❯ ss -plnt | grep java
LISTEN 0 1 [::ffff:127.0.0.1]:8006 *:* users:(("java",pid=27338,fd=52))
LISTEN 0 100 *:8005 *:* users:(("java",pid=27338,fd=43))
Install PlantUML and copy the .war file:
Use the latest release of plantuml-jsp
(for example: plantuml-jsp-v1.2024.8.war).
For context, see issue 265.
wget -P /tmp https://github.com/plantuml/plantuml-server/releases/download/v1.2024.8/plantuml-jsp-v1.2024.8.war
sudo cp /tmp/plantuml-jsp-v1.2024.8.war /opt/tomcat/webapps/plantuml.war
sudo chown tomcat:tomcat /opt/tomcat/webapps/plantuml.war
sudo systemctl restart tomcat
The Tomcat service should restart. After the restart is complete, the
PlantUML integration is ready and listening for requests on port 8005:
http://localhost:8005/plantuml.
To change the Tomcat defaults, edit the /opt/tomcat/conf/server.xml file.
[!note] The default URL is different when using this approach. The Docker-based image makes the service available at the root URL, with no relative path. Adjust the configuration below accordingly.
Next, you can:
proxy_pass port
configured in the link matches the Connector port in server.xml.The PlantUML server runs locally on your server, so it can't be accessed
externally by default. Your server must catch external PlantUML
calls to https://gitlab.example.com/-/plantuml/ and redirect them to the
local PlantUML server. Depending on your setup, the URL is either of the
following:
http://plantuml:8080/http://localhost:8080/plantuml/http://plantuml:8005/http://localhost:8005/plantuml/If you're running GitLab with TLS you must configure this redirection, because PlantUML uses the insecure HTTP protocol. Newer browsers don't load insecure HTTP resources on pages served over HTTPS.
If you can modify /etc/gitlab/gitlab.rb, configure the bundled NGINX to handle the redirection:
Add the following line in /etc/gitlab/gitlab.rb, depending on your setup method:
# Docker install
nginx['custom_gitlab_server_config'] = "location /-/plantuml/ { \n rewrite ^/-/plantuml/(.*) /$1 break;\n proxy_cache off; \n proxy_pass http://plantuml:8005/; \n}\n"
# Debian/Ubuntu install
nginx['custom_gitlab_server_config'] = "location /-/plantuml/ { \n rewrite ^/-/plantuml/(.*) /$1 break;\n proxy_cache off; \n proxy_pass http://localhost:8005/plantuml; \n}\n"
To activate the changes, run the following command:
sudo gitlab-ctl reconfigure
If you cannot modify the gitlab.rb file, configure your PlantUML server to use
HTTPS directly. This method is recommended for GitLab Dedicated instances.
This setup uses NGINX to handle SSL termination and proxy requests to the PlantUML container. You can also use cloud-based load balancers like AWS Application Load Balancer (ALB) for SSL termination.
Create an nginx.conf file:
events {
worker_connections 1024;
}
http {
server {
listen 443 ssl;
server_name _;
ssl_certificate /etc/nginx/ssl/plantuml.crt;
ssl_certificate_key /etc/nginx/ssl/plantuml.key;
location / {
proxy_pass http://plantuml: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;
}
}
}
Add the plantuml.crt and plantuml.key files to an ssl directory.
Configure the docker-compose.yml file:
version: '3.8'
services:
plantuml:
image: plantuml/plantuml-server:tomcat
container_name: plantuml
networks:
- plantuml-net
plantuml-ssl:
image: nginx
container_name: plantuml-ssl
ports:
- "8443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- plantuml
networks:
- plantuml-net
networks:
plantuml-net:
driver: bridge
Start your PlantUML server with docker-compose up.
Enable PlantUML integration with the URL
https://your-server:8443.
To verify the installation was successful:
Test the PlantUML server directly:
# Docker install
curl --location --verbose "http://localhost:8005/svg/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000"
# Debian/Ubuntu install
curl --location --verbose "http://localhost:8005/plantuml/svg/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000"
You should receive SVG output containing the text hello.
Test that GitLab can access PlantUML through NGINX by visiting:
http://gitlab.example.com/-/plantuml/svg/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000
Replace gitlab.example.com with your GitLab instance URL. You should see a rendered
PlantUML diagram displaying hello.
Bob -> Alice : hello
PlantUML has features that allow fetching network resources. If you self-host the PlantUML server, put network controls in place to isolate it. For example, make use of PlantUML's security profiles.
@startuml
start
' ...
!include http://localhost/
stop;
@enduml
When generating PlantUML diagrams in SVG format, configure your server for enhanced security. Disable the SVG output route in your NGINX configuration to prevent potential security issues.
To disable the SVG output route, add this configuration to your NGINX server hosting the PlantUML service:
location ~ ^/-/plantuml/svg/ {
return 403;
}
This configuration prevents potentially malicious diagram code from executing in browsers.
After configuring your local PlantUML server, you're ready to enable the PlantUML integration:
https://gitlab.example.com/-/plantuml/,
and select Save changes.To prevent browsers from sending diagram content to the external PlantUML service, use the diagram proxy.
Depending on your PlantUML and GitLab version numbers, you may also need to take these steps:
For PlantUML servers running v1.2020.9 and later, such as plantuml.com,
you must set the PLANTUML_ENCODING environment variable to enable the deflate
compression. In Linux package installations, you can set this value in /etc/gitlab/gitlab.rb with
this command:
gitlab_rails['env'] = { 'PLANTUML_ENCODING' => 'deflate' }
In GitLab Helm chart, you can set it by adding a variable to the global.extraEnv section, like this:
global:
extraEnv:
PLANTUML_ENCODING: deflate
deflate is the default encoding type for PlantUML. To use a different encoding type, PlantUML integration
requires a header prefix in the URL
to distinguish different encoding types.
Rendered diagrams are cached. To see the updates, try these steps:
If you're still not seeing the updated URL, check the following:
404 error when opening the PlantUML page in the browserYou might get a 404 error when visiting https://gitlab.example.com/-/plantuml/, when the PlantUML
server is set up in Debian or Ubuntu.
This can happen even when the integration is working. It does not necessarily indicate a problem with your PlantUML server or configuration.
To confirm if PlantUML is working correctly, you can verify the PlantUML installation.