InfoGrab DocsInfoGrab Docs

PlantUML

요약

PlantUML 통합을 사용해 스니펫, 위키, 리포지터리에서 다이어그램을 만듭니다. GitLab Self-Managed 인스턴스에서 이 통합을 설정하려면 PlantUML 서버를 구성해야 합니다. 통합을 완료하면 PlantUML 이 plantuml 블록을 소스가 PlantUML 인스턴스를 가리키는 HTML 이미지 태그로 변환합니다.

PlantUML 통합을 사용해 스니펫, 위키, 리포지터리에서 다이어그램을 만듭니다. GitLab.com은 모든 사용자에게 PlantUML 통합을 제공하며, 추가 구성이 필요하지 않습니다.

GitLab Self-Managed 인스턴스에서 이 통합을 설정하려면 PlantUML 서버를 구성해야 합니다.

통합을 완료하면 PlantUML 이 plantuml 블록을 소스가 PlantUML 인스턴스를 가리키는 HTML 이미지 태그로 변환합니다. PlantUML 다이어그램 구분자 @startuml/@enduml은 plantuml 블록으로 대체되므로 필요하지 않습니다.

  • .md 확장자를 사용하는 Markdown 파일:

    <div class="diagram-placeholder"><div class="diagram-placeholder-header">PlantUML 다이어그램 (2줄)</div><details><summary>소스 코드 보기</summary><pre><code>Bob -&gt; Alice : hello
    Alice -&gt; Bob : hi</code></pre></details></div>
    
    

    추가로 허용되는 확장자는 languages.yaml 파일에서 확인합니다.

  • .asciidoc, .adoc, .asc 확장자를 사용하는 AsciiDoc 파일:

    [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
    

    sphinxcontrib-plantuml과의 호환성을 위해 uml:: 지시자를 사용할 수 있지만, GitLab은 caption 옵션만 지원합니다.

PlantUML 서버가 올바르게 구성돼 있으면 다음 예시는 코드 블록 대신 다이어그램을 렌더링합니다.

PlantUML 다이어그램 (2줄)
소스 코드 보기
Bob -> Alice : hello
Alice -> Bob : hi

블록 안에는 PlantUML 이 지원하는 다이어그램을 넣을 수 있습니다. 예를 들면 다음과 같습니다.

블록 정의에는 파라미터를 추가합니다.

  • id: 다이어그램 HTML 태그에 추가되는 CSS ID.
  • width: 이미지 태그에 추가되는 width 속성.
  • height: 이미지 태그에 추가되는 height 속성.

Markdown은 파라미터를 지원하지 않으며, 항상 PNG 형식을 사용합니다.

다이어그램 파일 포함#

리포지터리의 별도 파일에 있는 PlantUML 다이어그램을 포함하거나 임베드하려면 include 지시자를 사용합니다. 복잡한 다이어그램을 전용 파일에서 관리하거나 다이어그램을 재사용할 때 이 방식을 사용합니다. 예를 들면 다음과 같습니다.

  • Markdown:

    <div class="diagram-placeholder"><div class="diagram-placeholder-header">PlantUML 다이어그램 (1줄)</div><details><summary>소스 코드 보기</summary><pre><code>::include{file=diagram.puml}</code></pre></details></div>
    
    
  • AsciiDoc:

    [plantuml, format="png", id="myDiagram", width="200px"]
    ----
    include::diagram.puml[]
    ----
    
Note

::include 지시자는 파일이 리포지터리에 커밋된 뒤에만 해석됩니다. Markdown 편집기 미리보기는 포함된 파일을 렌더링하지 않습니다. 다이어그램이 올바르게 렌더링되는지 확인하려면 파일을 커밋하고 리포지터리 파일 브라우저에서 확인합니다.

PlantUML 서버 구성#

GitLab에서 PlantUML을 활성화하기 전에 다이어그램을 생성할 자체 PlantUML 서버를 설정합니다.

Docker#

Docker에서 PlantUML 컨테이너를 실행하려면 다음 명령을 실행합니다.

docker run -d --name plantuml -p 8005:8080 plantuml/plantuml-server:tomcat

PlantUML URL은 컨테이너를 실행하는 서버의 호스트 이름입니다.

GitLab을 Docker에서 실행할 때는 GitLab 이 PlantUML 컨테이너에 접근할 수 있어야 합니다. 이를 위해 Docker Compose를 사용합니다. 다음 기본 docker-compose.yml 파일에서 GitLab은 PlantUML을 http://plantuml:8080/ URL로 사용할 수 있습니다.

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"

다음으로 아래 작업을 진행할 수 있습니다.

  1. 로컬 PlantUML 액세스 구성
  2. PlantUML 설치가 성공했는지 확인

Debian/Ubuntu#

Debian/Ubuntu 배포판에서는 Tomcat 또는 Jetty로 PlantUML 서버를 설치하고 구성할 수 있습니다. 아래 안내는 Tomcat 기준입니다.

사전 요구 사항:

  • JRE/JDK 11 이상 버전.
  • (권장) Jetty 11 이상 버전.
  • (권장) Tomcat 10 이상 버전.

설치#

PlantUML은 Tomcat 10.1 이상 설치를 권장합니다. 이 페이지는 기본 Tomcat 서버 설정만 다룹니다. 운영 환경에 더 적합한 구성은 Tomcat 문서를 참고합니다.

  1. JDK/JRE 11을 설치합니다.

    sudo apt update
    sudo apt install default-jre-headless graphviz git
    
  2. Tomcat 용 사용자를 추가합니다.

    sudo useradd -m -d /opt/tomcat -U -s /bin/false tomcat
    
  3. 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
    
  4. systemd 서비스를 생성합니다. /etc/systemd/system/tomcat.service 파일을 편집해 다음을 추가합니다.

    [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은 sudo update-java-alternatives -l에 표시되는 경로와 같아야 합니다.

  5. 포트를 구성하려면 /opt/tomcat/conf/server.xml을 편집해 사용할 포트를 선택합니다. 권장 설정은 다음과 같습니다.

    • Tomcat 종료 포트를 8005에서 8006으로 변경합니다.
    • Tomcat HTTP 엔드포인트에는 포트 8005를 사용합니다. 기본 포트 8080은 Puma가 메트릭용으로 포트 8080을 수신하므로 피해야 합니다.
    - 
    + 
    
    - 
    + 
    
  6. Tomcat을 다시 로드하고 시작합니다.

    sudo systemctl daemon-reload
    sudo systemctl start tomcat
    sudo systemctl status tomcat
    sudo systemctl enable tomcat
    

    Java 프로세스는 다음 포트를 수신해야 합니다.

    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))
    
  7. PlantUML을 설치하고 .war 파일을 복사합니다.

    plantuml-jsp의 최신 릴리스를 사용합니다 (예: plantuml-jsp-v1.2024.8.war). 배경은 이슈 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
    

Tomcat 서비스가 다시 시작됩니다. 재시작이 끝나면 PlantUML 통합이 준비되고 포트 8005에서 요청을 수신합니다. 주소는 다음과 같습니다. http://localhost:8005/plantuml.

Tomcat 기본값을 변경하려면 /opt/tomcat/conf/server.xml 파일을 편집합니다.

Note

이 방식에서는 기본 URL 이 다릅니다. Docker 기반 이미지는 상대 경로 없이 루트 URL에서 서비스를 제공합니다. 아래 구성을 그에 맞게 조정합니다.

다음으로 아래 작업을 진행할 수 있습니다.

  1. 로컬 PlantUML 액세스 구성. 링크에 구성된 proxy_pass 포트가 server.xml의 Connector 포트와 일치하는지 확인합니다.
  2. PlantUML 설치가 성공했는지 확인합니다.

로컬 PlantUML 액세스 구성#

PlantUML 서버는 사용자의 서버에서 로컬로 실행되므로 기본적으로 외부에서 접근할 수 없습니다. 서버는 https://gitlab.example.com/-/plantuml/로 들어오는 외부 PlantUML 호출을 받아 로컬 PlantUML 서버로 리디렉션해야 합니다. 설정에 따라 URL은 다음 중 하나입니다.

  • http://plantuml:8080/
  • http://localhost:8080/plantuml/
  • http://plantuml:8005/
  • http://localhost:8005/plantuml/

TLS를 사용하는 GitLab을 실행한다면 PlantUML 이 안전하지 않은 HTTP 프로토콜을 사용하므로 이 리디렉션을 구성해야 합니다. 최신 브라우저는 HTTPS로 제공되는 페이지에서 안전하지 않은 HTTP 리소스를 로드하지 않습니다.

번들된 GitLab NGINX 사용#

/etc/gitlab/gitlab.rb를 수정할 수 있다면, 번들된 NGINX가 리디렉션을 처리하도록 구성합니다.

  1. 설정 방법에 따라 /etc/gitlab/gitlab.rb에 다음 줄을 추가합니다.

    # 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"
    
  2. 변경 사항을 적용하려면 다음 명령을 실행합니다.

    sudo gitlab-ctl reconfigure
    

HTTPS PlantUML 서버 사용#

gitlab.rb 파일을 수정할 수 없다면 PlantUML 서버가 HTTPS를 직접 사용하도록 구성합니다. 이 방법은 GitLab Dedicated 인스턴스에 권장됩니다.

이 구성은 NGINX로 SSL 종료를 처리하고 요청을 PlantUML 컨테이너로 프록시합니다. AWS Application Load Balancer(ALB) 같은 클라우드 기반 로드 밸런서로 SSL 종료를 처리할 수도 있습니다.

  1. nginx.conf 파일을 생성합니다.

    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;
            }
        }
    }
    
  2. ssl 디렉터리에 plantuml.crt와 plantuml.key 파일을 추가합니다.

  3. docker-compose.yml 파일을 구성합니다.

    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
    
  4. docker-compose up으로 PlantUML 서버를 시작합니다.

  5. PlantUML 통합을 활성화합니다. URL은 https://your-server:8443 입니다.

PlantUML 설치 확인#

설치가 성공했는지 확인하는 절차는 다음과 같습니다.

  1. PlantUML 서버를 직접 테스트합니다.

    # Docker install
    curl --location --verbose "http://localhost:8005/svg/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000"
    
    # Debian/Ubuntu install
    curl --location --verbose "http://localhost:8005/plantuml/svg/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000"
    

    hello 텍스트가 포함된 SVG 출력을 받습니다.

  2. 다음 주소를 방문해 GitLab 이 NGINX를 통해 PlantUML에 접근할 수 있는지 테스트합니다.

    http://gitlab.example.com/-/plantuml/svg/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000
    

    gitlab.example.com을 GitLab 인스턴스 URL로 바꿉니다. hello를 표시하는 렌더링된 PlantUML 다이어그램이 보입니다.

    Bob -> Alice : hello
    

PlantUML 보안 구성#

PlantUML에는 네트워크 리소스를 가져오는 기능이 있습니다. PlantUML 서버를 직접 호스팅한다면 서버를 격리하는 네트워크 제어를 마련합니다. 예를 들어 PlantUML의 보안 프로파일을 활용합니다.

@startuml
start
    ' ...
    !include http://localhost/
stop;
@enduml

PlantUML SVG 다이어그램 출력 보안#

PlantUML 다이어그램을 SVG 형식으로 생성할 때는 보안을 강화하도록 서버를 구성합니다. 잠재적인 보안 문제를 막기 위해 NGINX 구성에서 SVG 출력 경로를 비활성화합니다.

SVG 출력 경로를 비활성화하려면 PlantUML 서비스를 호스팅하는 NGINX 서버에 다음 구성을 추가합니다.

location ~ ^/-/plantuml/svg/ {
    return 403;
}

이 구성은 악의적일 수 있는 다이어그램 코드가 브라우저에서 실행되는 것을 막습니다.

PlantUML 통합 활성화#

로컬 PlantUML 서버를 구성한 뒤에는 PlantUML 통합을 활성화할 수 있습니다.

  1. Administrator 사용자로 GitLab에 로그인합니다.
  2. 우측 상단에서 Admin을 선택합니다.
  3. 좌측 사이드바에서 Settings > General로 이동해 PlantUML 섹션을 확장합니다.
  4. Enable PlantUML 체크박스를 선택합니다.
  5. PlantUML 인스턴스를 https://gitlab.example.com/-/plantuml/로 설정하고 Save changes를 선택합니다.

브라우저가 외부 PlantUML 서비스로 다이어그램 콘텐츠를 보내지 않게 하려면 다이어그램 프록시를 사용합니다.

PlantUML과 GitLab 버전에 따라 다음 단계도 필요할 수 있습니다.

  • plantuml.com처럼 v1.2020.9 이상을 실행하는 PlantUML 서버에서는 deflate 압축을 활성화하기 위해 PLANTUML_ENCODING 환경 변수를 설정해야 합니다. Linux 패키지 설치에서는 다음 명령으로 /etc/gitlab/gitlab.rb에 이 값을 설정할 수 있습니다.

    gitlab_rails['env'] = { 'PLANTUML_ENCODING' => 'deflate' }
    

    GitLab Helm 차트에서는 global.extraEnv 섹션에 다음과 같이 변수를 추가해 설정할 수 있습니다.

    global:
    extraEnv:
      PLANTUML_ENCODING: deflate
    
  • deflate는 PlantUML의 기본 인코딩 유형입니다. 다른 인코딩 유형을 사용하려면 PlantUML 통합에는 서로 다른 인코딩 유형을 구분하기 위해 URL에 헤더 접두사가 필요합니다.

문제 해결#

업데이트 후에도 렌더링된 다이어그램 URL 이 그대로인 경우#

렌더링된 다이어그램은 캐시됩니다. 업데이트를 확인하려면 다음을 시도합니다.

  • 다이어그램이 Markdown 파일에 있으면 Markdown 파일을 조금 변경해 커밋합니다. 이렇게 하면 다시 렌더링됩니다.
  • Markdown 캐시를 무효화해 데이터베이스나 Redis에 캐시된 Markdown을 강제로 지웁니다.

업데이트된 URL 이 여전히 보이지 않으면 다음을 확인합니다.

  • GitLab 인스턴스에서 PlantUML 서버에 접근할 수 있는지 확인합니다.
  • GitLab 설정에서 PlantUML 통합이 활성화되어 있는지 확인합니다.
  • PlantUML 렌더링과 관련된 오류가 있는지 GitLab 로그를 확인합니다.
  • GitLab Redis 캐시를 지웁니다.

브라우저에서 PlantUML 페이지를 열 때 발생하는 404 오류#

PlantUML 서버를 Debian 또는 Ubuntu에 설정한 경우, https://gitlab.example.com/-/plantuml/를 방문하면 404 오류가 발생할 수 있습니다.

이 오류는 통합이 정상 동작할 때도 발생할 수 있습니다. 반드시 PlantUML 서버나 구성에 문제가 있음을 뜻하지는 않습니다.

PlantUML 이 올바르게 동작하는지 확인하려면 PlantUML 설치를 확인할 수 있습니다.

PlantUML

GitLab v19.5
Tier: Free, Premium, Ultimate
Offering: GitLab Self-Managed, GitLab Dedicated
원문 보기

요약

PlantUML 통합을 사용해 스니펫, 위키, 리포지터리에서 다이어그램을 만듭니다. GitLab Self-Managed 인스턴스에서 이 통합을 설정하려면 PlantUML 서버를 구성해야 합니다. 통합을 완료하면 PlantUML 이 plantuml 블록을 소스가 PlantUML 인스턴스를 가리키는 HTML 이미지 태그로 변환합니다.

PlantUML 통합을 사용해 스니펫, 위키, 리포지터리에서 다이어그램을 만듭니다. GitLab.com은 모든 사용자에게 PlantUML 통합을 제공하며, 추가 구성이 필요하지 않습니다.

GitLab Self-Managed 인스턴스에서 이 통합을 설정하려면 PlantUML 서버를 구성해야 합니다.

통합을 완료하면 PlantUML 이 plantuml 블록을 소스가 PlantUML 인스턴스를 가리키는 HTML 이미지 태그로 변환합니다. PlantUML 다이어그램 구분자 @startuml/@enduml은 plantuml 블록으로 대체되므로 필요하지 않습니다.

  • .md 확장자를 사용하는 Markdown 파일:

    <div class="diagram-placeholder"><div class="diagram-placeholder-header">PlantUML 다이어그램 (2줄)</div><details><summary>소스 코드 보기</summary><pre><code>Bob -&gt; Alice : hello
    Alice -&gt; Bob : hi</code></pre></details></div>
    
    

    추가로 허용되는 확장자는 languages.yaml 파일에서 확인합니다.

  • .asciidoc, .adoc, .asc 확장자를 사용하는 AsciiDoc 파일:

    [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
    

    sphinxcontrib-plantuml과의 호환성을 위해 uml:: 지시자를 사용할 수 있지만, GitLab은 caption 옵션만 지원합니다.

PlantUML 서버가 올바르게 구성돼 있으면 다음 예시는 코드 블록 대신 다이어그램을 렌더링합니다.

PlantUML 다이어그램 (2줄)
소스 코드 보기
Bob -> Alice : hello
Alice -> Bob : hi

블록 안에는 PlantUML 이 지원하는 다이어그램을 넣을 수 있습니다. 예를 들면 다음과 같습니다.

블록 정의에는 파라미터를 추가합니다.

  • id: 다이어그램 HTML 태그에 추가되는 CSS ID.
  • width: 이미지 태그에 추가되는 width 속성.
  • height: 이미지 태그에 추가되는 height 속성.

Markdown은 파라미터를 지원하지 않으며, 항상 PNG 형식을 사용합니다.

다이어그램 파일 포함#

리포지터리의 별도 파일에 있는 PlantUML 다이어그램을 포함하거나 임베드하려면 include 지시자를 사용합니다. 복잡한 다이어그램을 전용 파일에서 관리하거나 다이어그램을 재사용할 때 이 방식을 사용합니다. 예를 들면 다음과 같습니다.

  • Markdown:

    <div class="diagram-placeholder"><div class="diagram-placeholder-header">PlantUML 다이어그램 (1줄)</div><details><summary>소스 코드 보기</summary><pre><code>::include{file=diagram.puml}</code></pre></details></div>
    
    
  • AsciiDoc:

    [plantuml, format="png", id="myDiagram", width="200px"]
    ----
    include::diagram.puml[]
    ----
    
Note

::include 지시자는 파일이 리포지터리에 커밋된 뒤에만 해석됩니다. Markdown 편집기 미리보기는 포함된 파일을 렌더링하지 않습니다. 다이어그램이 올바르게 렌더링되는지 확인하려면 파일을 커밋하고 리포지터리 파일 브라우저에서 확인합니다.

PlantUML 서버 구성#

GitLab에서 PlantUML을 활성화하기 전에 다이어그램을 생성할 자체 PlantUML 서버를 설정합니다.

Docker#

Docker에서 PlantUML 컨테이너를 실행하려면 다음 명령을 실행합니다.

docker run -d --name plantuml -p 8005:8080 plantuml/plantuml-server:tomcat

PlantUML URL은 컨테이너를 실행하는 서버의 호스트 이름입니다.

GitLab을 Docker에서 실행할 때는 GitLab 이 PlantUML 컨테이너에 접근할 수 있어야 합니다. 이를 위해 Docker Compose를 사용합니다. 다음 기본 docker-compose.yml 파일에서 GitLab은 PlantUML을 http://plantuml:8080/ URL로 사용할 수 있습니다.

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"

다음으로 아래 작업을 진행할 수 있습니다.

  1. 로컬 PlantUML 액세스 구성
  2. PlantUML 설치가 성공했는지 확인

Debian/Ubuntu#

Debian/Ubuntu 배포판에서는 Tomcat 또는 Jetty로 PlantUML 서버를 설치하고 구성할 수 있습니다. 아래 안내는 Tomcat 기준입니다.

사전 요구 사항:

  • JRE/JDK 11 이상 버전.
  • (권장) Jetty 11 이상 버전.
  • (권장) Tomcat 10 이상 버전.

설치#

PlantUML은 Tomcat 10.1 이상 설치를 권장합니다. 이 페이지는 기본 Tomcat 서버 설정만 다룹니다. 운영 환경에 더 적합한 구성은 Tomcat 문서를 참고합니다.

  1. JDK/JRE 11을 설치합니다.

    sudo apt update
    sudo apt install default-jre-headless graphviz git
    
  2. Tomcat 용 사용자를 추가합니다.

    sudo useradd -m -d /opt/tomcat -U -s /bin/false tomcat
    
  3. 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
    
  4. systemd 서비스를 생성합니다. /etc/systemd/system/tomcat.service 파일을 편집해 다음을 추가합니다.

    [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은 sudo update-java-alternatives -l에 표시되는 경로와 같아야 합니다.

  5. 포트를 구성하려면 /opt/tomcat/conf/server.xml을 편집해 사용할 포트를 선택합니다. 권장 설정은 다음과 같습니다.

    • Tomcat 종료 포트를 8005에서 8006으로 변경합니다.
    • Tomcat HTTP 엔드포인트에는 포트 8005를 사용합니다. 기본 포트 8080은 Puma가 메트릭용으로 포트 8080을 수신하므로 피해야 합니다.
    - 
    + 
    
    - 
    + 
    
  6. Tomcat을 다시 로드하고 시작합니다.

    sudo systemctl daemon-reload
    sudo systemctl start tomcat
    sudo systemctl status tomcat
    sudo systemctl enable tomcat
    

    Java 프로세스는 다음 포트를 수신해야 합니다.

    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))
    
  7. PlantUML을 설치하고 .war 파일을 복사합니다.

    plantuml-jsp의 최신 릴리스를 사용합니다 (예: plantuml-jsp-v1.2024.8.war). 배경은 이슈 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
    

Tomcat 서비스가 다시 시작됩니다. 재시작이 끝나면 PlantUML 통합이 준비되고 포트 8005에서 요청을 수신합니다. 주소는 다음과 같습니다. http://localhost:8005/plantuml.

Tomcat 기본값을 변경하려면 /opt/tomcat/conf/server.xml 파일을 편집합니다.

Note

이 방식에서는 기본 URL 이 다릅니다. Docker 기반 이미지는 상대 경로 없이 루트 URL에서 서비스를 제공합니다. 아래 구성을 그에 맞게 조정합니다.

다음으로 아래 작업을 진행할 수 있습니다.

  1. 로컬 PlantUML 액세스 구성. 링크에 구성된 proxy_pass 포트가 server.xml의 Connector 포트와 일치하는지 확인합니다.
  2. PlantUML 설치가 성공했는지 확인합니다.

로컬 PlantUML 액세스 구성#

PlantUML 서버는 사용자의 서버에서 로컬로 실행되므로 기본적으로 외부에서 접근할 수 없습니다. 서버는 https://gitlab.example.com/-/plantuml/로 들어오는 외부 PlantUML 호출을 받아 로컬 PlantUML 서버로 리디렉션해야 합니다. 설정에 따라 URL은 다음 중 하나입니다.

  • http://plantuml:8080/
  • http://localhost:8080/plantuml/
  • http://plantuml:8005/
  • http://localhost:8005/plantuml/

TLS를 사용하는 GitLab을 실행한다면 PlantUML 이 안전하지 않은 HTTP 프로토콜을 사용하므로 이 리디렉션을 구성해야 합니다. 최신 브라우저는 HTTPS로 제공되는 페이지에서 안전하지 않은 HTTP 리소스를 로드하지 않습니다.

번들된 GitLab NGINX 사용#

/etc/gitlab/gitlab.rb를 수정할 수 있다면, 번들된 NGINX가 리디렉션을 처리하도록 구성합니다.

  1. 설정 방법에 따라 /etc/gitlab/gitlab.rb에 다음 줄을 추가합니다.

    # 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"
    
  2. 변경 사항을 적용하려면 다음 명령을 실행합니다.

    sudo gitlab-ctl reconfigure
    

HTTPS PlantUML 서버 사용#

gitlab.rb 파일을 수정할 수 없다면 PlantUML 서버가 HTTPS를 직접 사용하도록 구성합니다. 이 방법은 GitLab Dedicated 인스턴스에 권장됩니다.

이 구성은 NGINX로 SSL 종료를 처리하고 요청을 PlantUML 컨테이너로 프록시합니다. AWS Application Load Balancer(ALB) 같은 클라우드 기반 로드 밸런서로 SSL 종료를 처리할 수도 있습니다.

  1. nginx.conf 파일을 생성합니다.

    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;
            }
        }
    }
    
  2. ssl 디렉터리에 plantuml.crt와 plantuml.key 파일을 추가합니다.

  3. docker-compose.yml 파일을 구성합니다.

    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
    
  4. docker-compose up으로 PlantUML 서버를 시작합니다.

  5. PlantUML 통합을 활성화합니다. URL은 https://your-server:8443 입니다.

PlantUML 설치 확인#

설치가 성공했는지 확인하는 절차는 다음과 같습니다.

  1. PlantUML 서버를 직접 테스트합니다.

    # Docker install
    curl --location --verbose "http://localhost:8005/svg/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000"
    
    # Debian/Ubuntu install
    curl --location --verbose "http://localhost:8005/plantuml/svg/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000"
    

    hello 텍스트가 포함된 SVG 출력을 받습니다.

  2. 다음 주소를 방문해 GitLab 이 NGINX를 통해 PlantUML에 접근할 수 있는지 테스트합니다.

    http://gitlab.example.com/-/plantuml/svg/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000
    

    gitlab.example.com을 GitLab 인스턴스 URL로 바꿉니다. hello를 표시하는 렌더링된 PlantUML 다이어그램이 보입니다.

    Bob -> Alice : hello
    

PlantUML 보안 구성#

PlantUML에는 네트워크 리소스를 가져오는 기능이 있습니다. PlantUML 서버를 직접 호스팅한다면 서버를 격리하는 네트워크 제어를 마련합니다. 예를 들어 PlantUML의 보안 프로파일을 활용합니다.

@startuml
start
    ' ...
    !include http://localhost/
stop;
@enduml

PlantUML SVG 다이어그램 출력 보안#

PlantUML 다이어그램을 SVG 형식으로 생성할 때는 보안을 강화하도록 서버를 구성합니다. 잠재적인 보안 문제를 막기 위해 NGINX 구성에서 SVG 출력 경로를 비활성화합니다.

SVG 출력 경로를 비활성화하려면 PlantUML 서비스를 호스팅하는 NGINX 서버에 다음 구성을 추가합니다.

location ~ ^/-/plantuml/svg/ {
    return 403;
}

이 구성은 악의적일 수 있는 다이어그램 코드가 브라우저에서 실행되는 것을 막습니다.

PlantUML 통합 활성화#

로컬 PlantUML 서버를 구성한 뒤에는 PlantUML 통합을 활성화할 수 있습니다.

  1. Administrator 사용자로 GitLab에 로그인합니다.
  2. 우측 상단에서 Admin을 선택합니다.
  3. 좌측 사이드바에서 Settings > General로 이동해 PlantUML 섹션을 확장합니다.
  4. Enable PlantUML 체크박스를 선택합니다.
  5. PlantUML 인스턴스를 https://gitlab.example.com/-/plantuml/로 설정하고 Save changes를 선택합니다.

브라우저가 외부 PlantUML 서비스로 다이어그램 콘텐츠를 보내지 않게 하려면 다이어그램 프록시를 사용합니다.

PlantUML과 GitLab 버전에 따라 다음 단계도 필요할 수 있습니다.

  • plantuml.com처럼 v1.2020.9 이상을 실행하는 PlantUML 서버에서는 deflate 압축을 활성화하기 위해 PLANTUML_ENCODING 환경 변수를 설정해야 합니다. Linux 패키지 설치에서는 다음 명령으로 /etc/gitlab/gitlab.rb에 이 값을 설정할 수 있습니다.

    gitlab_rails['env'] = { 'PLANTUML_ENCODING' => 'deflate' }
    

    GitLab Helm 차트에서는 global.extraEnv 섹션에 다음과 같이 변수를 추가해 설정할 수 있습니다.

    global:
    extraEnv:
      PLANTUML_ENCODING: deflate
    
  • deflate는 PlantUML의 기본 인코딩 유형입니다. 다른 인코딩 유형을 사용하려면 PlantUML 통합에는 서로 다른 인코딩 유형을 구분하기 위해 URL에 헤더 접두사가 필요합니다.

문제 해결#

업데이트 후에도 렌더링된 다이어그램 URL 이 그대로인 경우#

렌더링된 다이어그램은 캐시됩니다. 업데이트를 확인하려면 다음을 시도합니다.

  • 다이어그램이 Markdown 파일에 있으면 Markdown 파일을 조금 변경해 커밋합니다. 이렇게 하면 다시 렌더링됩니다.
  • Markdown 캐시를 무효화해 데이터베이스나 Redis에 캐시된 Markdown을 강제로 지웁니다.

업데이트된 URL 이 여전히 보이지 않으면 다음을 확인합니다.

  • GitLab 인스턴스에서 PlantUML 서버에 접근할 수 있는지 확인합니다.
  • GitLab 설정에서 PlantUML 통합이 활성화되어 있는지 확인합니다.
  • PlantUML 렌더링과 관련된 오류가 있는지 GitLab 로그를 확인합니다.
  • GitLab Redis 캐시를 지웁니다.

브라우저에서 PlantUML 페이지를 열 때 발생하는 404 오류#

PlantUML 서버를 Debian 또는 Ubuntu에 설정한 경우, https://gitlab.example.com/-/plantuml/를 방문하면 404 오류가 발생할 수 있습니다.

이 오류는 통합이 정상 동작할 때도 발생할 수 있습니다. 반드시 PlantUML 서버나 구성에 문제가 있음을 뜻하지는 않습니다.

PlantUML 이 올바르게 동작하는지 확인하려면 PlantUML 설치를 확인할 수 있습니다.