PlantUML 문법으로 다이어그램을 코드처럼 관리하기
PlantUML DSL 문법과 렌더링 엔진 선택지를 정리하고, 시퀀스·컴포넌트·클래스 다이어그램을 텍스트로 작성해 자동 생성하는 실전 방법을 다룬다.
2026-08-12 · 최초 발행 2025-10-31
PlantUML이 다이어그램을 텍스트로 다루는 방식
PlantUML은 UML, C4, 시퀀스, 클래스, 컴포넌트, 상태, 활동 등 다양한 다이어그램을 텍스트 DSL로 표현하고 SVG나 PNG로 렌더링하는 도구다. 동작 구조는 단순하다 — PlantUML DSL을 렌더러(Java 기반, 내부적으로 Graphviz DOT 활용)에 넣으면 SVG/PNG/ASCII 형태로 출력물이 나온다. 로컬 CLI, Docker, 서버(PlantUML Server, Kroki) 중 어떤 방식으로도 구동 가능하다.
Markdown이나 AsciiDoc 문서 안에 코드 펜스로 삽입하고, IDE 플러그인과 CI/CD를 연계하면 변경 추적과 자동 배포까지 이어진다. 다이어그램이 코드 리포지토리 안에서 텍스트로 존재한다는 것 자체가 핵심이다 — diff로 변경을 확인하고, 리뷰하고, 버전을 고정할 수 있다.
핵심 문법: 엔티티·관계·스타일링
DSL의 뼈대는 세 가지다.
- 엔티티 정의: class, component, participant 같은 키워드로 요소를 선언한다.
- 관계·메시지:
->,-->,..>로 화살표 종류를 구분한다. - 그룹화·라벨링: package, rectangle로 묶고
:label로 이름을 붙인다.
스타일은 skinparam, theme, sprite로 색상·폰트·여백을 통제한다. 다이어그램 수가 많아질수록 이 스타일 통일이 문서 전체의 일관된 룩앤필을 좌우한다.
렌더링 엔진과 실행 환경
렌더링은 두 축으로 나뉜다. 하나는 Java JAR + Graphviz DOT 조합이나 Docker 이미지(plantuml/plantuml)를 로컬에서 돌리는 방식, 다른 하나는 PlantUML Server나 Kroki 같은 서버형으로 HTTP 요청을 받아 렌더링하는 방식이다. 출력 포맷은 SVG가 우선이다 — 벡터라 링크·검색에 유리하다. PNG, ASCII, LaTeX도 지원하며, 대량 렌더링이 필요하면 병렬 처리와 캐시로 속도를 끌어올린다.
로컬/컨테이너 방식은 데이터 유출 위험이 낮은 대신 초기 셋업이 필요하고, 서버형은 중앙집중 운영이 가능한 대신 네트워크·권한 관리가 따라붙는다. 입력 검증, 리소스 제한, 네임스페이스 분리가 안전성의 기본이고, 외부 테마·아이콘에 의존한다면 라이선스도 확인해야 한다.
확장 생태계
Visual Studio Code, IntelliJ, Eclipse 같은 IDE/에디터 플러그인과 MkDocs, Sphinx, Docusaurus, AsciiDoctor 같은 문서 툴이 PlantUML을 직접 지원한다. C4-PlantUML, ArchiMate 아이콘, OpenAPI/DB 스키마 연계 같은 도메인 확장도 있어서, 조직 표준 템플릿·테마를 한 번 만들어두면 여러 팀에서 재사용할 수 있다.
저장소에서 자동으로 다이어그램 생성하기
Git에 DSL을 저장해두면 PR 리뷰에서 다이어그램 변경 diff를 그대로 확인할 수 있다. CI에서는 빌드·품질 게이트·아티팩트 배포까지 자동화한다. 아래는 push 시 Docker로 PlantUML을 렌더링해 SVG 아티팩트를 만드는 최소 구성이다.
name: render-plantuml
on:
push:
branches: [main]
pull_request:
jobs:
build-diagrams:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Render with Docker
run: |
docker run --rm -v "$PWD:/ws" -w /ws plantuml/plantuml:1.2024.6 \
-DREL=$GITHUB_SHA -tsvg -o out diagrams/**/*.puml
- uses: actions/upload-artifact@v4
with:
name: diagrams
path: diagrams/out/**/*.svg
버전 고정(컨테이너 태그, jar 버전)과 커밋 해시 삽입만 지켜도 다이어그램 재현성은 대부분 확보된다.
실전 예시: 시퀀스·컴포넌트·클래스 다이어그램
유즈케이스나 API 흐름은 시퀀스로, 배치·의존성은 컴포넌트로 표현하는 것이 기본이다. 팀 공통 템플릿을 정해두면 코드나 로그를 파싱해 반자동으로 .puml을 생성하는 것도 가능하다 — 최신성을 유지하기 쉬워진다.
시퀀스 다이어그램:
@startuml
title 결제 승인 흐름
actor User
participant Web as "WebApp"
participant Pay as "Payment API"
database DB
User -> Web: 결제 요청
Web -> Pay: POST /authorize
Pay --> Web: 200 OK(txId)
Web -> DB: insert(txId, status=AUTH)
Web --> User: 승인 완료
@enduml
컴포넌트 다이어그램:
@startuml
skinparam componentStyle rectangle
package "Payment Domain" {
[WebApp] --> [Payment API]
[Payment API] --> [Gateway]
}
database "Orders DB" as DB
[WebApp] ..> DB : JDBC
@enduml
DDL이나 OpenAPI 스펙을 스키마 파서로 돌려 클래스/관계 .puml을 생성하는 패턴도 흔하다. 변경 이벤트가 생길 때마다 재생성하면 도메인 모델 문서가 코드와 어긋나지 않는다.
@startuml
class Order {
+id: UUID
+status: Status
+total: Money
}
class LineItem {
+productId: UUID
+qty: int
}
Order "1" o-- "*" LineItem
enum Status {
PENDING
PAID
SHIPPED
}
@enduml
Markdown 문서에는 코드 펜스로 원본을 그대로 포함시키고, CI에서 필터링해 렌더링한다. Kroki 서버를 쓰면 문서 렌더러가 HTTP로 자동 변환해준다.
```plantuml
@startuml
participant A
A -> B: hello
@enduml
```
생성 파이프라인 한눈에 보기
입력부터 배포까지의 흐름을 도식화하면 다음과 같다.
운영 관점에서 챙길 포인트는 네 가지다. 입력 단계에서는 조직 표준 테마와 C4 템플릿을 주입하고 plantuml lint로 사전 검증한다. 처리 단계는 -tsvg를 기본으로 하되 병렬 처리 시 -Xmx 제한과 작업 큐를 나눈다. 출력에는 버전·커밋 해시를 삽입하고 접근성 대체 텍스트 메타를 붙인다. 에러가 나면 CI를 실패시키고 로그를 PR 코멘트로 돌려준다.
설치, 실행, 성능 튜닝
전제조건은 둘 중 하나다. Docker 24+ 에 plantuml/plantuml:1.2024.6 이미지를 쓰거나, Java 17+ 와 Graphviz 2.44+, plantuml-1.2024.6.jar를 로컬에 둔다. 네트워크가 격리된 환경이라면 캐시 디렉터리 권한도 미리 정리해두는 게 좋다.
# Docker
docker run --rm -v "$PWD:/ws" -w /ws plantuml/plantuml:1.2024.6 -tsvg -o out diagrams/*.puml
# Java JAR
java -Xmx512m -jar plantuml-1.2024.6.jar -graphvizdot "/usr/local/bin/dot" -tsvg -o out diagrams
레포 규모가 커지면 변경된 파일만 증분 렌더링하고 아티팩트를 캐시한다. 공통 include(.iuml)와 테마를 분리해 리소스를 공유하고, 서버형이라면 렌더 큐·워커 수·요청 크기 제한·타임아웃을 별도로 조정한다.
보안 측면에서는 로컬/컨테이너 방식이 소스 유출을 막는 대신 CI 에이전트 리소스 관리가 필요하고, 서버형은 TLS·인증 역프록시·입력 검증·렌더 타임아웃/메모리 제한이 필수다. 멀티테넌시 환경이라면 네임스페이스 분리나 레이트리밋도 고려 대상이다. 테마·아이콘의 외부 의존성은 라이선스·감사 관점에서 별도로 관리하고, 릴리스 태깅과 아티팩트 서명을 도입해두면 나중에 덜 아프다.
도구 비교
| 도구 | 성능 | 확장성 | 일관성 | 안정성 | 운영 편의 |
|---|---|---|---|---|---|
| PlantUML | 중상: 캐시/병렬로 향상 | 높음: C4·테마·서버 | 높음: DSL·테마 | 높음: 버전 고정 | 중: Java/Graphviz 요구 |
| Mermaid | 중: 브라우저/정적 | 중: 기능 한정 | 중: 렌더러별 차이 | 중: 브라우저 의존 | 상: Markdown 즉시 사용 |
| draw.io | 중하: 대규모 시 저하 | 낮음: 수동 편집 | 중하: 작성자 편차 | 중: 파일 손상 리스크 낮음 | 상: GUI 친화 |
비고: 환경·버전에 따라 결과가 달라질 수 있으니 최신 정보를 확인하는 게 안전하다.
도입 효과는 수치로도 드러난다. 수동 편집 대비 다이어그램 작성·갱신 시간이 3060% 줄고, 리뷰 사이클은 2040% 단축된다. 설계 변경 추적성이 좋아지고 아키텍처 규약 위반 검출률이 올라가며, 다이어그램과 코드의 불일치가 줄어든다. 테마·템플릿을 표준화하면 신규 멤버 온보딩도 빨라지고, 재현 가능한 빌드·캐시 덕분에 렌더링 실패율과 시간도 함께 줄어든다.
가장 먼저 손댈 곳은 시퀀스·컴포넌트 다이어그램이다. 여기서 조직 표준 테마와 템플릿을 정립한 뒤 클래스·상태·배포 다이어그램으로 점진적으로 넓혀가는 순서가 무리가 없다.