Django 아키텍처 2부: Container Diagram으로 백엔드 구조 정리하기

2부에서는 Container Diagram에 대해서 이야기 해보려고 하는데요. 第1部에서 시스템 컨텍스트 다이어그램으로 “이 시스템이 세상과 어떻게 연결돼 있는지”를 그려봤죠.
이제 한 단계 안으로 들어가서,
“시스템 안에는 어떤 구성요소(컨테이너) 들이 있고
서로 어떻게 통신하는가?”
를 보여주는 것이 바로 컨테이너 다이어그램(Container Diagram)です。
여기서 말하는 컨테이너(Container) は
도커 컨테이너가 아니라, 역할 단위의 실행 컴포넌트라고 이해하시면 편해요.
- Web App (Django)
- Background Worker (Celery)
- Database (Postgres / SQLite)
- Cache (Redis 또는 LocMem)
- Message Broker
- Static file server
- SMTP / Gmail
이런 것들이 전부 컨테이너가 되고,
이들을 연결해서 그린 그림이 바로 컨테이너 다이어그램입니다.
오늘 만들 컨테이너 다이어그램 구조 미리 보기

위와 같이 생성된 container.png는 대략 이런 구성을 담고 있습니다.
- 위쪽
- Web User (브라우저 사용하는 관리자/응답자/분석자)
- 중앙 – Survey System 내부 컨테이너
- Django Web App
- HTTP 요청 처리, 템플릿 렌더링, REST API 제공
- Celery Worker
- 이메일 보내기, 대량 통계 처리 같은 백그라운드 작업
- Database (SQLite / Postgres)
- 설문, 면담, 응답, 조직, 사용자 데이터 저장
- Cache (LocMem / Redis)
- 세션/캐시
- Static files
- CSS, JS, 이미지 등 정적 파일
- Message broker (RabbitMQ / Redis)
- Celery 큐
- SMTP / Gmail
- 이메일 발송
- Django Web App
이걸 텍스트로 모델링한 후 PlantUML로 그리면,
이쁜 컨테이너 다이어그램 PNG가 딱! 생성됩니다.
파일 준비 – container.puml 만들기
1부에서 만든 폴더를 그대로 씁니다.
# 이미 있다면 건너뛰기
mkdir -p docs/architectureさあ docs/architecture/container.puml 파일을 만들고 편집기를 열어요.
컨테이너 다이어그램 기본 템플릿 코드
아래 코드를 통째로 붙여 넣으면,
현재 시스템과 거의 같은 컨테이너 다이어그램(Container Diagram)이 나옵니다.
@startuml
' C4-PlantUML 컨테이너 다이어그램용 라이브러리
!define C4P https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master
!includeurl C4P/C4_Container.puml
' 1) 사람(사용자) 정의
Person(web_user, "Web User", "브라우저로 설문에 응답하거나 면담을 관리하는 사용자")
' 2) 시스템 전체 박스
System_Boundary(survey_system, "Survey System") {
' 2-1) Django 웹 애플리케이션
Container(django_app, "Django Web App", "Python / Django",
"HTTP 요청 처리, 템플릿 렌더링, REST API 제공")
' 2-2) 백그라운드 작업용 Celery 워커
Container(celery_worker, "Celery Worker", "Python / Celery",
"이메일 발송, 대량 통계 처리 등 비동기 작업 실행")
' 2-3) 데이터베이스
ContainerDb(database, "Database", "SQLite (dev) / Postgres (prod)",
"사용자, 설문, 응답, 면담 기록 등 영속 데이터 저장")
' 2-4) 캐시 / 세션 저장소
Container(cache, "Cache / Session Store", "LocMemCache / Redis",
"세션, 빈번히 조회되는 데이터 캐시")
' 2-5) 정적 파일 서버
Container(static_files, "Static Files", "Nginx 또는 Django",
"CSS, JS, 이미지 같은 정적 자산 제공")
' 2-6) 메시지 브로커 (Celery 큐)
Container(message_broker, "Message Broker", "Redis / RabbitMQ",
"Celery 백그라운드 작업 큐")
' 2-7) 이메일 발송용 SMTP
Container_Ext(smtp, "SMTP / Gmail", "외부 이메일 서비스",
"알림, 인터뷰 초대 메일 발송")
}
' 3) 관계(Relationship) 정의
Rel(web_user, django_app, "HTTP 요청/응답 (설문, 면담, 대시보드)", "HTTPS")
Rel(django_app, database, "ORM으로 읽기/쓰기", "SQL")
Rel(django_app, cache, "세션/캐시 읽기·쓰기", "TCP")
Rel(django_app, static_files, "정적 파일 요청", "HTTP")
Rel(django_app, message_broker, "백그라운드 작업 enqueue", "AMQP / Redis")
Rel(django_app, smtp, "알림 이메일 발송", "SMTP")
Rel(celery_worker, database, "백그라운드에서 데이터 읽기·쓰기", "SQL")
Rel(celery_worker, message_broker, "작업 수신", "AMQP / Redis")
Rel(celery_worker, smtp, "대량 이메일 발송", "SMTP")
SHOW_LEGEND()
@enduml이 코드가 바로 두 번째 그림인 Container Diagram의 소스에 해당합니다.
컨테이너 다이어그램 라인별 해설

1) System_Boundary 블록
System_Boundary(survey_system, "Survey System") { ... }- Survey System이라는 하나의 큰 상자 안에
여러 개의 컨테이너를 묶어줍니다. - 1부의 시스템 Container Diagram에서의 “System”을
내부 구조로 쪼갠 버전이라고 보면 돼요.
2) Django Web App 컨테이너
Container(django_app, "Django Web App", "Python / Django",
"HTTP 요청 처리, 템플릿 렌더링, REST API 제공")- URL, 뷰, 템플릿, DRF(API) 같은 주요 웹 로직이 다 여기.
- 나중에 Container Diagram을 보면서
“이 기능은 Celery Worker로 빼야겠다” 같은 리팩토링 아이디어를 얻기 쉽습니다.
3) Celery Worker 컨테이너
Container(celery_worker, "Celery Worker", "Python / Celery",
"이메일 발송, 대량 통계 처리 등 비동기 작업 실행")- 장고에서
delay()로 보내는 작업들이 도는 곳. - 무거운 통계, 리포트 생성, 대량 이메일 등은
Container Diagram 상에서 항상 Worker 쪽으로 빼두면 구조가 깔끔해집니다.
4) Database / Cache / Static Files
- Database 컨테이너는 Django ORM이 붙는 쪽
- Cache 컨테이너는 세션/캐시 역할
- Static Files 컨테이너는 Nginx든, S3든, 정적 자산을 주는 역할
실제 구현은 조금씩 달라도,
컨테이너 다이어그램에서는 “역할” 기준으로만 깔끔하게 나누는 게 핵심입니다.
5) Message Broker + SMTP
Container Diagram에서 이 둘은 “외부이지만 시스템에 강하게 묶인” 느낌으로 표현합니다.
- Message Broker: Celery가 의존하는 큐 시스템
- SMTP: 외부 메일 서버지만, 서비스 입장에서 거의 필수 인프라
이렇게 적어두면, 나중에
“RabbitMQ에서 Redis로 바꿀까?”
“내부 SMTP 서버로 바꿀까?”
같은 논의가 나올 때
컨테이너 다이어그램을 기준으로 자연스럽게 이야기할 수 있습니다.
컨테이너 다이어그램 렌더링 (PNG 생성)
VSCode 플러그인일 때
container.puml파일 열기- 미리보기 실행 → Container Diagram이 보이는지 확인
- 우클릭 → Export as PNG (확장에 따라 기능 이름이 조금 다를 수 있어요)
plantuml.jar일 때
java -jar tools/plantuml.jar docs/architecture/container.puml실행 후 docs/architecture/container.png가 만들어지면,
이걸 사용하고자 하는 곳에 업로드해서 “Container Diagram” 설명섹션으로 사용하면 됩니다.
실무에서 컨테이너 다이어그램 활용 팁 3가지
- 배포 구조 논의의 기준으로 사용
- “Django Web App은 몇 개?”
- “Worker는 Auto Scaling 필요?”
- “Redis는 세션/브로커 겸용인가, 분리인가?”
이런 얘기를 할 때 컨테이너 다이어그램을 앞에 두고 회의하면
말이 훨씬 빨리 통합니다.
- 장애 원인 정리 때 사용
- 예: “Message Broker 장애 → Celery Worker → Django Web App 응답 지연”
이런 식으로 장애 경로를 컨테이너 다이어그램 위에 표시하면
보고서나 회의자료로도 훌륭합니다.
- 예: “Message Broker 장애 → Celery Worker → Django Web App 응답 지연”
- 미래 구조(타겟 아키텍처) 그릴 때 복제해서 사용
- 현재 구조(Container Diagram V1)와
- 목표 구조(Container Diagram V2)를 두 장으로 만들어 두면
“무엇을 바꿀지”가 확실해집니다.
컨테이너 다이어그램을 이렇게 써먹다 보면
자연스럽게 3부에서 다룰 컴포넌트 다이어그램으로 내려가는 흐름도 잡히게 돼요.






