Target Infrastructure Plan
이 문서는 현재 기준의 권장 인프라 방향을 정리합니다. 기본 방향은 생성/후처리 실행부는 컨테이너로 분리하고, 상태 저장 핵심 자원은 managed service로 둔다는 것입니다.
결론
local: MacBook Docker Compose + AWS SQS/S3
dev: EC2 Docker Compose + AWS SQS/S3
prod: app EC2와 AI EC2를 분리한 Docker Compose부터 시작, 수요 증가 후 ASG/ECS/Kubernetes
이미지/비디오 생성은 ComfyUI가 직접 무거운 로컬 추론을 수행하는 방식이 아니라, 가능한 한 ComfyUI API 노드와 외부 생성 API provider를 호출하는 구조를 기본값으로 둡니다. 이 경우 ai-node-agent와 post-processing-worker는 저렴한 CPU VM/Pod에서도 운영할 수 있습니다.
컴포넌트 역할
| 컴포넌트 | 역할 |
|---|---|
frontend-vivid-ai | 사용자 UI. 생성 요청, 진행 상태 표시, 결과 조회를 담당합니다. |
backend-vivid-ai | 인증, 결제/크레딧, workflow template 처리, DB 상태 관리, SQS enqueue, realtime gateway를 담당합니다. |
ComfyUI | workflow 실행 엔진입니다. workflow JSON을 받아 API 노드 또는 로컬 노드를 실행하고 output 파일을 생성합니다. |
ai-node-agent | 생성 orchestration worker입니다. SQS generation queue를 polling하고, ComfyUI를 호출하며, 진행 상태를 relay/backend에 전달하고, raw output을 S3 raw/ prefix에 업로드한 뒤 후처리 queue로 넘깁니다. |
post-processing-worker | media finalization worker입니다. S3 raw/ prefix의 output을 다운로드해 thumbnail, preview, resize, crop, transcode 등을 수행하고 S3 creations/ prefix와 backend에 최종 결과를 반영합니다. |
| SQS | generation job과 post-processing job을 분리하는 durable queue입니다. local/dev/prod 모두 cloud SQS를 사용합니다. |
| S3 | 환경별 media bucket입니다. raw/, creations/, generation/source/, generation/work-input/, temp/ 등 prefix로 역할을 분리합니다. |
| Redis/ElastiCache | progress cache, pub/sub, websocket 상태, rate limit 등 유실 가능하거나 재구성 가능한 상태에 사용합니다. |
| Postgres/RDS | user, creation, billing, credit, asset metadata 등 source of truth입니다. |
ai-node-agent와 post-processing-worker라는 이름은 그대로 유지합니다. 문서상으로는 각각 media generation orchestrator, media finalization worker로 정의합니다.
End-to-End Flow
User
-> frontend
-> backend
-> SQS generation queue
-> ai-node-agent
-> ComfyUI
-> external image/video API node
-> S3 raw/
-> SQS post-processing queue
-> post-processing-worker
-> S3 creations/
-> backend
-> Postgres / Redis
-> frontend realtime update
ComfyUI와 ai-node-agent는 같은 생성 단계에 있지만 책임이 다릅니다.
ComfyUI = workflow execution engine
ai-node-agent = SQS/S3/backend/realtime orchestration layer
환경별 구성
| 환경 | 실행부 | Postgres | Redis | Queue | Storage |
|---|---|---|---|---|---|
| local | MacBook Docker Compose | local container | local container | AWS SQS local queues | AWS S3 local bucket/prefix |
| dev | EC2 Docker Compose | EC2 container | EC2 container | AWS SQS dev queues | AWS S3 dev bucket/prefix |
| prod | EC2 Docker Compose 초기 운영, 이후 ASG/Kubernetes | RDS | ElastiCache | AWS SQS prod queues | AWS S3 prod bucket/prefix |
Local
로컬 개발 환경은 MacBook에서 Docker Compose로 전체 실행부를 띄우는 것을 기본으로 합니다.
Docker Compose
- frontend
- backend
- comfyui
- ai-node-agent
- post-processing-worker
- redis
- postgres
Cloud
- SQS local queues
- S3 local bucket or local prefix
SQS는 비용이 낮고 실제 운영과 동일한 동작을 검증할 수 있으므로 LocalStack 대신 AWS SQS를 사용합니다. 단, local queue와 prod queue는 반드시 분리합니다.
Dev
Dev 환경은 처음에는 EC2 한 대에서 Docker Compose로 운영합니다. 생성/후처리 실행부는 컨테이너로 나누고, 상태 저장 자원은 AWS managed service를 사용합니다.
EC2 Docker Compose
- frontend
- backend
- postgres
- redis
- comfyui
- ai-node-agent
- post-processing-worker
AWS Managed
- SQS
- S3
API 노드 기반 generation만 수행한다면 t3.medium급 VM부터 시작할 수 있습니다. t3.small은 비용은 낮지만 RAM 2GiB라서 backend, ComfyUI, worker를 함께 띄우기에는 빠듯할 수 있습니다.
dev는 비용을 우선하여 PostgreSQL과 Redis도 EC2 내부 container로 시작합니다. dev DB 초기화가 허용된다는 전제입니다. dev 데이터 보존과 prod 유사성이 중요해지면 RDS/ElastiCache로 분리합니다.
Prod
Prod 환경은 초기 유료 운영부터 app 실행부와 AI 실행부를 분리합니다. 상세 기준은 초기 Production 인프라를 따릅니다.
prod-app-01 (t3.medium)
- frontend
- backend
- post-processing-worker
prod-ai-01 (t3.medium)
- comfyui
- ai-node-agent
Managed
- RDS Postgres
- ElastiCache Redis
- SQS
- S3
초기 prod는 app server와 AI server를 모두 t3.medium으로 시작합니다. 생성 대기 시간이 늘면 t3.medium AI server를 추가하고, app server가 CPU/RAM 병목을 보이면 t3.large로 올리거나 두 번째 app server를 추가합니다. Kubernetes는 여러 worker pool, autoscaling, rolling deploy, queue-depth 기반 scaling이 필요한 시점에 도입합니다.
Kubernetes로 전환할 경우 ai-node-agent와 ComfyUI는 파일 시스템을 공유해야 하므로 같은 Pod 안의 두 컨테이너로 묶는 구성이 자연스럽습니다.
Pod: ai-node
- container: comfyui
- container: ai-node-agent
- shared volume: input/output/temp
운영 정책상 독립 스케일링이 더 중요해지면 ComfyUI와 ai-node-agent를 별도 Deployment로 분리할 수 있습니다. 이 경우 output 전달 방식과 shared volume 전략을 별도로 정해야 합니다.
Queue And Storage Naming
환경별 리소스는 이름부터 분리합니다.
surfai-computation-queue-local
surfai-post-processing-worker-queue-local
surfai-computation-queue-dev
surfai-post-processing-worker-queue-dev
surfai-computation-queue-prod
surfai-post-processing-worker-queue-prod
S3는 환경별 media bucket을 분리하고, bucket 내부 prefix로 raw output, 최종 결과, 입력 원본, 임시 파일을 구분합니다. 세부 설정은 S3 media bucket 설정을 따릅니다.
s3://<local-media-bucket>/raw/...
s3://<local-media-bucket>/creations/...
s3://<local-media-bucket>/generation/source/...
s3://<dev-media-bucket>/raw/...
s3://<dev-media-bucket>/creations/...
s3://<dev-media-bucket>/generation/source/...
s3://<prod-media-bucket>/raw/...
s3://<prod-media-bucket>/creations/...
s3://<prod-media-bucket>/generation/source/...
현재 코드의 S3_TEMP_BUCKET_{ENV}_NAME, S3_PERMANENT_BUCKET_{ENV}_NAME 환경 변수명은 유지합니다. 단일 media bucket을 사용하는 환경에서는 두 값을 같은 bucket 이름으로 지정하고, raw/와 creations/ prefix로 역할을 나눕니다.
Managed Boundary
다음 자원은 prod 기준으로 managed service로 유지합니다. dev는 비용 우선 환경이므로 PostgreSQL/Redis container를 허용합니다.
- Postgres/RDS: 결제, 크레딧, creation history, asset metadata 등 source of truth를 저장합니다. dev는 비용 우선으로 EC2 내부 PostgreSQL container를 허용하지만 prod는 RDS 또는 동급 managed Postgres를 사용합니다.
- SQS: generation/post-processing job의 durable queue입니다.
- S3: media asset 저장소입니다. raw output과 최종 결과는 별도 bucket이 아니라 prefix로 분리할 수 있습니다.
- ElastiCache: prod의 Redis 역할을 담당합니다. dev는 비용 우선으로 EC2 내부 Redis container를 허용합니다.
Redis는 local/dev에서는 container로 충분합니다. prod에서는 ElastiCache를 사용하여 backend와 worker가 같은 progress/cache/pubsub 상태를 안정적으로 공유합니다.
Postgres는 Redis와 달리 유실되면 안 되는 원장이므로 prod에서는 k8s Pod나 일반 container로 직접 운영하지 않고 RDS 또는 동급 managed Postgres를 사용합니다.
Scaling Plan
초기에는 dev EC2 한 대와 prod app/AI EC2 각 한 대에서 운영합니다. 병목이 보이면 아래 순서로 확장합니다.
- AI queue latency가 늘면
prod-ai-02t3.medium을 추가합니다. - 각 AI EC2에는
ComfyUI + ai-node-agent한 묶음을 둡니다. - App server CPU/RAM이 부족하면
prod-app-01을 t3.large로 올립니다. - App server 단일 장애점 또는 트래픽 분산이 필요하면
prod-app-02t3.medium을 추가하고 ALB를 둡니다. post-processing-worker병목이 보이면 별도 worker EC2 또는 ECS task로 분리합니다.- image job과 video job queue를 분리합니다.
- ASG/ECS/Kubernetes를 도입합니다.
- 외부 생성 API provider의 rate limit 또는 비용이 병목이 되면 provider 분산 또는 전용 worker pool을 추가합니다.
영상 job은 파일 크기와 transcode 비용이 크므로 image job보다 보수적인 concurrency를 둡니다.
image generation: AI node 1개당 1 job, AI server 수로 수평 확장
video generation: 1-2 concurrent jobs부터 시작
video post-processing: 1-2 concurrent jobs부터 시작
Security Rules
- 외부 생성 API key는 frontend에 노출하지 않고
ai-node-agent/ComfyUI 서버 환경변수 또는 secret으로만 주입합니다. - local/dev/prod SQS queue와 S3 bucket/prefix를 분리합니다.
- prod EC2는 instance profile/IAM role을 사용하고, 장기 AWS access key를 이미지나 secret에 넣지 않습니다. Kubernetes 전환 후에는 IRSA를 사용합니다.
- local/dev credential은 prod queue와 prod bucket에 접근하지 못하도록 제한합니다.
- user credit과 billing 상태는 Postgres를 source of truth로 둡니다.
Historical Documents
현재 기본 계획은 API 노드 기반 generation과 컨테이너화된 worker 구조입니다. 무거운 로컬 추론 전제의 인프라 문서는 기준 문서에서 제거합니다.