Docker - 100-hours-a-week/3-team-ssammu-wiki GitHub Wiki

๐Ÿ“ ์ปจํ…Œ์ด๋„ˆ ๊ตฌ์กฐ ๋‹ค์ด์–ด๊ทธ๋žจ

CareerBee_Docker drawio

๐Ÿงฑ ์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ(AWS)

  • VPC (SSMU-DEV)
    • CIDR: 192.168.0.0/16
  • Public Subnet
    • ๋ฆฌ์ „: ap-northeast-2, ๊ฐ€์šฉ ์˜์—ญ: ap-northeast-2a, ap-northeast-2c
    • SUBNET-SSMU-DEV-PUBLIC-AZONE: 192.168.10.0/24
    • SUBNET-SSMU-DEV-PUBLIC-CZONE: 192.168.110.0/24
  • Nat Subnet
    • ๋ฆฌ์ „: ap-northeast-2, ๊ฐ€์šฉ ์˜์—ญ: ap-northeast-2a, ap-northeast-2c
    • SUBNET-SSMU-DEV-NAT-AZONE: 192.168.20.0/24
    • SUBNET-SSMU-DEV-NAT-CZONE: 192.168.120.0/24
  • Private Subnet
    • ๋ฆฌ์ „: ap-northeast-2, ๊ฐ€์šฉ ์˜์—ญ: ap-northeast-2a, ap-northeast-2c
    • SUBNET-SSMU-DEV-PRIVATE-AZONE: 192.168.30.0/24
    • SUBNET-SSMU-DEV-PRIVATE-CZONE: 192.168.130.0/24
  • EC2 (FE + BE)
    • ํ”„๋ก ํŠธ/๋ฐฑ์—”๋“œ ์„œ๋ฒ„๊ฐ€ ๊ฐ๊ฐ Docker ์ปจํ…Œ์ด๋„ˆ๋กœ ๊ตฌ๋™๋˜๋Š” ์ธ์Šคํ„ด์Šค
    • t3.medium2๋Œ€ ์‚ฌ์šฉ(Auto-Scaling Group)
    • docker-compose๋ช…๋ น์–ด๋ฅผ ์ด์šฉํ•ด ์„œ๋ฒ„๋ฅผ ๊ฐ€๋™
    • FE๋Š” Nginx ์ปจํ…Œ์ด๋„ˆ์™€ ํ•จ๊ป˜ ๊ตฌ๋™๋˜๋ฉฐ, ์ •์  ํŒŒ์ผ์„ ์„œ๋น„์Šคํ•˜๋Š” ์—ญํ•  ์ˆ˜ํ–‰
    • Docker ๋„คํŠธ์›Œํฌ ๊ตฌ์„ฑ: bridge ๊ธฐ๋ฐ˜ ์ปค์Šคํ…€ ๋„คํŠธ์›Œํฌ app-net ์‚ฌ์šฉํ•˜์—ฌ FE/BE ๊ฐ„ ๋‚ด๋ถ€ ํ†ต์‹  ๊ฐ€๋Šฅ
  • EC2 (OpenVPN)
    • OpenVPN AMI๋กœ ์ƒ์„ฑํ•œ ์ธ์Šคํ„ด์Šค
    • t3.micro ์‚ฌ์šฉ
    • ๊ณ ์ • ํผ๋ธ”๋ฆญ IP๊ฐ€ ํ• ๋‹น๋˜์–ด ์žˆ์œผ๋ฉฐ, ๋ณด์•ˆ ์ ‘์†์šฉ VPN ๊ฒŒ์ดํŠธ์›จ์ด ์—ญํ• 
    • ๊ฐœ๋ฐœ์ž๋Š” ์ด ์ธ์Šคํ„ด์Šค๋ฅผ ํ†ตํ•ด ํ”„๋ผ์ด๋น— ์ธ์Šคํ„ด์Šค์— ์ ‘๊ทผ
  • EC2 (Database Master/Replica)
    • ๋ฐฑ์—”๋“œ ์„œ๋ฒ„์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋น„์Šค๋ฅผ ์„ค์น˜ํ•  ์ธ์Šคํ„ด์Šค
    • t3.micro 2๋Œ€ ์‚ฌ์šฉ(๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ด์ค‘ํ™” - Read Replica)
    • docker run๋ช…๋ น์–ด๋ฅผ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„(RDBMS)๋ฅผ ๊ฐ€๋™
    • ๋ณ„๋„์˜ private subnet์— ์œ„์น˜ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋ณด์กด์„ฑ๊ณผ ์•ˆ์ •์„ฑ ํ™•๋ณด
  • Route53
    • ๋„๋ฉ”์ธ ๊ด€๋ฆฌ ์„œ๋น„์Šค
    • ์‚ฌ์šฉ์ž ์š”์ฒญ์„ ALB๋ฅผ ํ†ตํ•ด EC2 ์ธ์Šคํ„ด์Šค๋กœ ์ „๋‹ฌ(๋„๋ฉ”์ธ๊ณผ ์—ฐ๊ฒฐ๋จ)
  • S3 Bucket(images)
    • ์ •์  ๋ฆฌ์†Œ์Šค(์ด๋ฏธ์ง€, ํŒŒ์ผ ๋“ฑ) ์ €์žฅ ์šฉ๋„๋กœ ์—ฐ๋™
    • ํ–ฅํ›„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๊ทธ ๋ฐ ๋ถ„์„ ๋ฐ์ดํ„ฐ๋ฅผ ์ ์žฌํ•˜๋Š” ์šฉ๋„๋กœ๋„ ํ™•์žฅ ๊ฐ€๋Šฅ
  • Developer
    • GitHub Actions๋ฅผ ํ†ตํ•ด ๋นŒ๋“œ๋œ Docker ์ด๋ฏธ์ง€๋ฅผ ECR์— Push
    • OpenVPN์„ ํ†ตํ•ด ์ธ์Šคํ„ด์Šค์— ์ ‘๊ทผํ•˜์—ฌ docker-compose pull โ†’ up -d ๋ช…๋ น์œผ๋กœ ๋ฐฐํฌ ์ˆ˜ํ–‰

๐Ÿงฑ ์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ (GCP)

  • VPC (SSMU-AI)
    • CIDR: 10.0.0.0/16
  • Public Subnet (SUBNET-SSMU-AI-PUBLIC)
    • CIDR: 10.0.10.0/24
  • GCP Compute Engine โ€“ AI ์„œ๋ฒ„ (Standard VM)
    • Chroma DB/FastAPI ์„œ๋ฒ„๊ฐ€ ๊ฐ๊ฐ Docker ์ปจํ…Œ์ด๋„ˆ๋กœ ๊ตฌ๋™๋˜๋Š” ์ธ์Šคํ„ด์Šค
    • e2-medium ์‚ฌ์šฉ
    • Docker ๋„คํŠธ์›Œํฌ ๊ตฌ์„ฑ: ์‚ฌ์šฉ์ž ์ •์˜ ๋„คํŠธ์›Œํฌ ai-net์„ ํ™œ์šฉํ•˜์—ฌ FastAPI โ†” ChromaDB ๊ฐ„ ํ†ต์‹  ๊ตฌํ˜„
  • GCP Compute Engine โ€“ GPU ์„œ๋ฒ„ (AI ๋ชจ๋ธ ์ „์šฉ)
    • AI ๋ชจ๋ธ (LLM ๊ธฐ๋ฐ˜ ์ถ”๋ก  ์„œ๋ฒ„)์„ ๊ตฌ๋™ํ•˜๋Š” ์ธ์Šคํ„ด์Šค
    • g2-standard-8 ์‚ฌ์šฉ

โš“ ์ปจํ…Œ์ด๋„ˆ ๋ฐฐํฌ ์ „๋žต ์„ค๊ณ„

๐Ÿงฉ ๋„์ž… ๋ฐฐ๊ฒฝ ๋ฐ ํ•„์š”์„ฑ

  • ํ™˜๊ฒฝ ์ผ๊ด€์„ฑ ํ™•๋ณด: ๊ฐœ๋ฐœ์ž์˜ ๋กœ์ปฌ ํ™˜๊ฒฝ๊ณผ ์„œ๋ฒ„ ํ™˜๊ฒฝ ๊ฐ„์˜ ์ฐจ์ด(์˜ˆ: OS, ํŒจํ‚ค์ง€ ๋ฒ„์ „, ์„ค์ • ํŒŒ์ผ ๋“ฑ)๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์‹คํ–‰ ์˜ค๋ฅ˜๋ฅผ ์ œ๊ฑฐ
  • ๋ฐฐํฌ ์†๋„ ๊ฐœ์„ : ์ด๋ฏธ์ง€ ๋‹จ์œ„ ๋ฐฐํฌ๋กœ ํ‰๊ท  ๋ฐฐํฌ ์‹œ๊ฐ„ 15~20๋ถ„ โ†’ 5๋ถ„ ์ด๋‚ด๋กœ ๋‹จ์ถ•
  • ์šด์˜ ์ž๋™ํ™” ๊ธฐ๋ฐ˜ ๋งˆ๋ จ: GitHub Actions + ECR ์—ฐ๊ณ„๋กœ ์ž๋™ํ™” ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ ๋„์ž…
  • ์˜์กด์„ฑ ๊ด€๋ฆฌ ์šฉ์ด: ๊ฐ ์„œ๋น„์Šค ๋Ÿฐํƒ€์ž„์„ ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์—์„œ ๋…๋ฆฝ์ ์œผ๋กœ ๊ตฌ์„ฑ ๊ฐ€๋Šฅ
  • ํ™•์žฅ์„ฑ ํ™•๋ณด: ํ–ฅํ›„ ECS ๋˜๋Š” Kubernetes ํ™˜๊ฒฝ์œผ๋กœ์˜ ์ „ํ™˜๋„ ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์‘ ๊ฐ€๋Šฅ

๐Ÿงณ FE/BE/AI ์„œ๋น„์Šค ๋‹จ์œ„ ์ปจํ…Œ์ด๋„ˆํ™”์˜ ํ•„์š”์„ฑ

  • ํ˜„์žฌ ์šฐ๋ฆฌ ์„œ๋น„์Šค๋Š” ์Šคํ”„๋ฆฐํŠธ ๊ธฐ๊ฐ„ ๋‚ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ ์—…๋ฐ์ดํŠธ๊ฐ€ ์˜ˆ์ •๋˜์–ด ์žˆ์œผ๋ฉฐ, ๊ฐ๊ฐ์˜ ๊ธฐ๋Šฅ์ด ์•ˆ์ •์ ์ด๊ณ  ๋…๋ฆฝ์ ์œผ๋กœ ์šด์˜๋˜์–ด์•ผ ํ•œ๋‹ค:

    1๏ธโƒฃ ์ด๋ ฅ์„œ ์ดˆ์•ˆ ์ž๋™ ์ž‘์„ฑ ๊ธฐ๋Šฅ โ€“ ๋ฐฑ์—”๋“œ ๋ฐ AI ์„œ๋ฒ„ ์—ฐ๋™ ์ค‘์‹ฌ

    2๏ธโƒฃ ์ผ์ผ CS ๋Œ€ํšŒ ๋ฐ ๋žญํ‚น ์‹œ์Šคํ…œ โ€“ ์ •ํ™•ํ•œ ์‹œ๊ฐ„์— ๋ฐฐํฌ๋˜์–ด์•ผ ํ•˜๋Š” ๋ฐฑ์—”๋“œ ์ค‘์‹ฌ ๊ธฐ๋Šฅ

    3๏ธโƒฃ IT ๊ธฐ์—… ์ถ”์ฒœ ๋ฐ ์‹œ๊ฐํ™” โ€“ ํ”„๋ก ํŠธ์—”๋“œ ๋ฐ AI ์—ฐ๊ณ„ ํ•„์š”

    4๏ธโƒฃ ๋ฉด์ ‘ ์งˆ๋ฌธ ํ๋ ˆ์ดํŒ… ๋ฐ ๋‹ต๋ณ€ ์ฒจ์‚ญ ๊ธฐ๋Šฅ โ€“ FastAPI ๊ธฐ๋ฐ˜ AI ๋ถ„์„ ๋กœ์ง์ด ๋ณ„๋„๋กœ ๊ตฌ๋™๋จ

    ์ด์ฒ˜๋Ÿผ ํ”„๋ก ํŠธ์—”๋“œ, ๋ฐฑ์—”๋“œ, AI ๋ถ„์„ ๋กœ์ง์ด ๋ช…ํ™•ํžˆ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์œผ๋ฉฐ, ์ปจํ…Œ์ด๋„ˆํ™”๋ฅผ ํ†ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์ ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค:

    • ๋…๋ฆฝ์ ์ธ ๋นŒ๋“œ ๋ฐ ๋ฐฐํฌ: ์˜ˆ๋ฅผ ๋“ค์–ด AI ๋ถ„์„ ๋ชจ๋ธ๋งŒ ์—…๋ฐ์ดํŠธํ•˜๋”๋ผ๋„ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋Š” ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์Œ
    • ์žฅ์•  ์ „ํŒŒ ์ฐจ๋‹จ: ํ•˜๋‚˜์˜ ์ปจํ…Œ์ด๋„ˆ์— ์žฅ์• ๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ๋‹ค๋ฅธ ์„œ๋น„์Šค๋Š” ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์Œ
    • ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ ๋ฐ ๋น ๋ฅธ ๋กค๋ฐฑ: ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ๊ธฐ๋ฐ˜ ๋ฐฐํฌ๋กœ ์งง์€ ๋‹ค์šดํƒ€์ž„ ๋‚ด ๋ฐฐํฌ ๊ฐ€๋Šฅ
    • ์ •์‹œ ์šด์˜ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์‹ ๋ขฐ๋„ ํ™•๋ณด: ์ผ์ผ ๋Œ€ํšŒ์™€ ๊ฐ™์€ ์ด๋ฒคํŠธ ์ค‘์‹ฌ ๊ธฐ๋Šฅ์ด ํŠน์ • ์‹œ๊ฐ„์— ๋งž์ถฐ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, ๋ฐฑ์—”๋“œ์˜ ์‹คํ–‰ ํ™˜๊ฒฝ์„ ๊ณ ์ •ํ•˜๊ณ , ์ปจํ…Œ์ด๋„ˆ ๋‹จ์œ„๋กœ ๋ฐฐํฌํ•จ์œผ๋กœ์จ ์‹คํ–‰ ์‹œ์ ์˜ ์˜ˆ์ธก ๊ฐ€๋Šฅ์„ฑ๊ณผ ์•ˆ์ •์„ฑ์„ ํ™•๋ณด

๋„์ž… ๋ฒ”์œ„

์„œ๋น„์Šค ๋„์ž… ์—ฌ๋ถ€ ๋„์ž… ์ด์œ 
ํ”„๋ก ํŠธ์—”๋“œ (Next.js + Vite) โœ… ์ •์  ๋ฆฌ์†Œ์Šค๋ฅผ ์ด๋ฏธ์ง€๋กœ ํŒจํ‚ค์ง•ํ•˜์—ฌ ๋นŒ๋“œ โ†’ ์ „์†ก ๊ตฌ์กฐ ๋‹จ์ˆœํ™”
๋ฐฑ์—”๋“œ (Spring Boot) โœ… .jar ์‹คํ–‰ ํ™˜๊ฒฝ์„ Docker ์ด๋ฏธ์ง€ํ™”ํ•˜์—ฌ ๋ฐฐํฌ ํŽธ์˜์„ฑ ํ–ฅ์ƒ
AI ์„œ๋ฒ„ (FastAPI) โœ… Python + Uvicorn ํ™˜๊ฒฝ ๋ฐ ์˜์กด์„ฑ ํŒจํ‚ค์ง€๋ฅผ ํฌํ•จํ•œ ์ด๋ฏธ์ง€ ๊ตฌ์„ฑ์œผ๋กœ ์‹คํ–‰ ์•ˆ์ •์„ฑ ํ™•๋ณด
DB (MySQL) โœ… MySQL ์„œ๋ฒ„๋ฅผ Docker๋กœ ์ปจํ…Œ์ด๋„ˆํ™”ํ•˜์—ฌ Master/Replica ์šด์˜
DB (Chroma) โœ… ๋ฒกํ„ฐ ๊ฒ€์ƒ‰์šฉ DB๋กœ FastAPI์™€ ํ•จ๊ป˜ GCP VM์— Docker ์ปจํ…Œ์ด๋„ˆ๋กœ ๋ฐฐํฌ๋˜์–ด ๋น ๋ฅธ ํ†ต์‹  ๋ฐ ๋ฆฌ์†Œ์Šค ๋ถ„๋ฆฌ ํ™•๋ณด

โฑ๏ธ Big Bang ๋ฐฐํฌ vs Docker ๊ธฐ๋ฐ˜ ๋ฐฐํฌ ์†Œ์š” ์‹œ๊ฐ„ ๋น„๊ต

ํ•ญ๋ชฉ Big Bang ๋ฐฐํฌ (๊ธฐ์กด) Docker ๊ธฐ๋ฐ˜ ๋ฐฐํฌ (ECR + Compose)
ํ”„๋ก ํŠธ ์ „์†ก ๋ฐ ์ ์šฉ scp ์ „์†ก + Nginx ์žฌ์‹œ์ž‘ (3~5๋ถ„) docker-compose pull + up -d (30์ดˆ~1๋ถ„)
๋ฐฑ์—”๋“œ ๊ต์ฒด ๋ฐ ์‹คํ–‰ scp ์ „์†ก + PID kill + JAR ์‹คํ–‰ (5~7๋ถ„) docker-compose pull + up -d (1๋ถ„ ๋‚ด์™ธ)
AI ์„œ๋ฒ„ ์žฌ์‹œ์ž‘ venv ์„ค์ • + ์˜์กด์„ฑ ์„ค์น˜ + uvicorn ์‹คํ–‰ (5๋ถ„ ์ด์ƒ) docker-compose pull + up -d (30์ดˆ~1๋ถ„)
๋กœ๊ทธ ํ™•์ธ ๋ฐ ์ „์ฒด ํ™•์ธ ์ˆ˜๋™ ๋กœ๊ทธ tail/grep (2~3๋ถ„) ์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ ํ™•์ธ (docker ps, logs) (1๋ถ„ ์ด๋‚ด)
์ด ์†Œ์š” ์‹œ๊ฐ„ ํ‰๊ท  20~30๋ถ„ ํ‰๊ท  2~5๋ถ„

ํŠนํžˆ FastAPI ๊ธฐ๋ฐ˜ AI ์„œ๋ฒ„๋Š” ์˜์กด์„ฑ ์„ค์น˜๋งŒ ํ•ด๋„ ์ˆ˜ ๋ถ„์ด ์†Œ์š”๋  ์ˆ˜ ์žˆ์œผ๋‚˜, Docker ์ด๋ฏธ์ง€ ๋‚ด์—์„œ ๋ฏธ๋ฆฌ ์„ค์น˜๋˜๋ฏ€๋กœ ๋งค ๋ฐฐํฌ ์‹œ๋งˆ๋‹ค ์ ˆ๊ฐ ํšจ๊ณผ๊ฐ€ ํฌ๋‹ค.

์™œ ์‹ค์งˆ์ ์œผ๋กœ ๋น ๋ฅธ๊ฐ€?

  • Docker๋Š” ๋ฏธ๋ฆฌ ๋นŒ๋“œ๋œ ํ™˜๊ฒฝ์„ ๊ฐ€์ ธ์˜จ๋‹ค
    • ๊ธฐ์กด์—๋Š” ์„œ๋ฒ„๋งˆ๋‹ค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜ ๋ฐ ์„ค์ •์„ ๋ฐ˜๋ณต
    • Docker๋Š” ์ด๋ฏธ์ง€ ๋‚ด์— ์ด ๋ชจ๋“  ํ™˜๊ฒฝ์ด ๋ฏธ๋ฆฌ ์„ค์ •๋˜์–ด ์žˆ์–ด pull๊ณผ run๋งŒ์œผ๋กœ ์ฆ‰์‹œ ์‹คํ–‰
  • ๋‹จ์ผ ํŒŒํŠธ๋งŒ ๋น ๋ฅด๊ฒŒ ์žฌ๋ฐฐํฌ ๊ฐ€๋Šฅ
    • ์˜ˆ๋ฅผ ๋“ค์–ด AI ์„œ๋ฒ„๋งŒ ์ˆ˜์ •ํ–ˆ์„ ๋•Œ ์ „์ฒด ์žฌ๋ฐฐํฌ๊ฐ€ ํ•„์š” ์—†์ด ํ•ด๋‹น ์ปจํ…Œ์ด๋„ˆ๋งŒ ์žฌ์‹คํ–‰

๐Ÿ–ผ๏ธ ์ด๋ฏธ์ง€ ๊ด€๋ฆฌ ์ „๋žต

๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๋„์ž… - AWS Elastic Container Registry

ํ•ญ๋ชฉ ECR ์„ ํƒ ์ด์œ 
๋ณด์•ˆ ๋ฐ ๊ถŒํ•œ ์ œ์–ด AWS IAM์„ ํ†ตํ•œ ์„ธ๋ถ„ํ™”๋œ ์ ‘๊ทผ ์ œ์–ด ๊ฐ€๋Šฅ โ€“ ๊ฐœ๋ฐœ์ž๋ณ„ Push/Pull ๊ถŒํ•œ ์„ค์ • ๊ฐ€๋Šฅ
์š”๊ธˆ ๋ฐ ํšจ์œจ Docker Hub์™€ ๋‹ฌ๋ฆฌ Pull rate ์ œํ•œ ์—†์Œ โ€“ ๋น„๊ณต๊ฐœ ์ด๋ฏธ์ง€์— ์ตœ์ 
์„ฑ๋Šฅ EC2์™€ ๋™์ผํ•œ ๋ฆฌ์ „ ๋‚ด ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์ด๋ฏ€๋กœ ์ด๋ฏธ์ง€ Pull ์†๋„ ๋น ๋ฆ„
CI/CD ํ†ตํ•ฉ GitHub Actions + AWS ECR ๊ณต์‹ ์•ก์…˜ ์—ฐ๋™์œผ๋กœ ์ž๋™ํ™” ์‰ฌ์›€
์•„ํ‚คํ…์ฒ˜ ํ†ตํ•ฉ์„ฑ ํ•˜๋‚˜์˜ AWS ๊ณ„์ • ๋‚ด์—์„œ ๋นŒ๋“œ, ๋ฐฐํฌ, ์ด๋ฏธ์ง€ ๋ณด๊ด€๊นŒ์ง€ ํ†ตํ•ฉ ๊ด€๋ฆฌ ๊ฐ€๋Šฅ

๐Ÿท๏ธ ํƒœ๊น… ์ „๋žต

ํƒœ๊ทธ ๋ช… ์šฉ๋„ ์ƒ์„ฑ ์‹œ์  ๋น„๊ณ 
dev-<์ปค๋ฐ‹ํ•ด์‹œ> ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ํ…Œ์ŠคํŠธ์šฉ dev ๋ธŒ๋žœ์น˜ ๋นŒ๋“œ ์‹œ QA ์„œ๋ฒ„ ๋“ฑ์— ์‚ฌ์šฉ, ์ปค๋ฐ‹ ๊ธฐ๋ฐ˜ ์ถ”์  ๊ฐ€๋Šฅ
prod-<๋ฆด๋ฆฌ์ฆˆ๋ฒ„์ „> ์šด์˜ ํ™˜๊ฒฝ ๋ฐ˜์˜ main ๋ฐฐํฌ ์Šน์ธ ์‹œ ์šด์˜ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ณ ์ • ๋ฒ„์ „

๐Ÿš€ ๋ฐฐํฌ ์ „๋žต ์„ ํƒ โ€“ Rolling Update vs Blue-Green

๋‘ ๋ฐฐํฌ ์ „๋žต์€ ์ปจํ…Œ์ด๋„ˆ ๊ธฐ๋ฐ˜ ์‹œ์Šคํ…œ์—์„œ ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ๋ฅผ ์‹คํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๋Œ€ํ‘œ์ ์ธ ๋ฐฉ์‹์ด๋‹ค. ๋‹ค์Œ์€ ๊ฐ ๋ฐฉ์‹์˜ ๊ฐœ์š”์ด๋‹ค:

  • Rolling Update: ์ „์ฒด ์ธ์Šคํ„ด์Šค๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ๊ต์ฒดํ•˜๋Š” ๋ฐฉ์‹. ํŠธ๋ž˜ํ”ฝ์€ ํ•ญ์ƒ ์ผ๋ถ€ ์ธ์Šคํ„ด์Šค๋ฅผ ํ†ตํ•ด ์œ ์ง€๋˜๋ฏ€๋กœ ๋‹ค์šดํƒ€์ž„์ด ๊ฑฐ์˜ ์—†์Œ
  • Blue-Green Deployment: ํ˜„์žฌ ์šด์˜ ์ค‘์ธ ๋ฒ„์ „(Blue)๊ณผ ์‹ ๊ทœ ๋ฐฐํฌ ๋ฒ„์ „(Green)์„ ๋ณ‘๋ ฌ๋กœ ์œ ์ง€ํ•œ ๋’ค, ํŠธ๋ž˜ํ”ฝ์„ Green์œผ๋กœ ์ „ํ™˜ํ•˜๋Š” ๋ฐฉ์‹. ์žฅ์•  ๋ฐœ์ƒ ์‹œ Blue๋กœ ๋กค๋ฐฑ ๊ฐ€๋Šฅ
์ „๋žต ์žฅ์  ๋‹จ์  ์šฐ๋ฆฌ ์„œ๋น„์Šค์™€์˜ ์ ํ•ฉ์„ฑ
Rolling Update ์ ์ง„์  ์—…๋ฐ์ดํŠธ - ๋‹ค์šดํƒ€์ž„ ์ตœ์†Œํ™” - ์ž์› ํšจ์œจ์  ์ค‘๊ฐ„ ๋‹จ๊ณ„์—์„œ ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ ๋กค๋ฐฑ ์–ด๋ ค์›€ - ๋น ๋ฅด๊ฒŒ ์„ฑ์žฅํ•˜๋ฉฐ ๊ธฐ๋Šฅ์ด ์ž์ฃผ ์ถ”๊ฐ€๋˜๋Š” ์šฐ๋ฆฌ ์„œ๋น„์Šค ๊ฐœ๋ฐœ ํ๋ฆ„์— ์ ํ•ฉ
- ์‹คํ—˜์  ๊ธฐ๋Šฅ ์ถ”๊ฐ€ ์‹œ ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์‘ ๊ฐ€๋Šฅ
Blue-Green Deployment ์™„์ „ํ•œ ์ด์ „ ๋ฒ„์ „ ๋ณด์กด - ๋ฐฐํฌ ์‹คํŒจ ์‹œ ์†์‰ฌ์šด ๋กค๋ฐฑ ๊ฐ€๋Šฅ ์ž์› ๋‘ ๋ฐฐ ์‚ฌ์šฉ - ๋ฆฌ์†Œ์Šค ์ œ์•ฝ์ด ์žˆ๋Š” ํ˜„์žฌ ๊ตฌ์กฐ์—์„œ๋Š” ๋‹ค์†Œ ๋ถ€๋‹ด
- EC2, GCE ๊ธฐ๋ฐ˜ ๋ฐฐํฌ ๊ตฌ์กฐ์™€ ์ž˜ ๋งž์ง€ ์•Š์Œ

๐Ÿ”น ๋”ฐ๋ผ์„œ Rolling Update ์ „๋žต์„ ์šฐ์„  ์ ์šฉํ•˜๊ณ , ์ตœ์ข…์ ์œผ๋กœ Kubernetes ํ™˜๊ฒฝ์œผ๋กœ ์ „ํ™˜ ์‹œ Helm ๋˜๋Š” ArgoCD ๊ธฐ๋Šฅ์„ ํ†ตํ•œ Blue-Green ์ „๋žต์€ ํ›„์ผ ๋ถ€๊ฐ€์ ์œผ๋กœ ๊ณ ๋ คํ•œ๋‹ค.

โ™ป๏ธ ๋กค๋ฐฑ ์ „๋žต(ECR ํƒœ๊ทธ ๊ธฐ๋ฐ˜)

  • ๊ฐ ๋นŒ๋“œ ์‹œ์ ๋งˆ๋‹ค prod-<๋ฆด๋ฆฌ์ฆˆ๋ฒ„์ „> ํ˜•์‹์˜ ๊ณ ์ • ํƒœ๊ทธ์™€ ํ•จ๊ป˜ rollback-<timestamp> ํ˜•ํƒœ์˜ ํƒœ๊ทธ๋„ ํ•จ๊ป˜ ๊ด€๋ฆฌํ•จ
  • ์žฅ์•  ๋ฐœ์ƒ ์‹œ, ์ด์ „ ์ •์ƒ ์ž‘๋™ํ–ˆ๋˜ ํƒœ๊ทธ๋ฅผ ๊ธฐ์ค€์œผ๋กœ docker-compose.yml์˜ ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋ฅผ ์ˆ˜์ •
  • GitHub Actions ์›Œํฌํ”Œ๋กœ์šฐ ๋‚ด์—์„œ ๊ณผ๊ฑฐ ํƒœ๊ทธ๋กœ pull ํ›„ ์žฌ๋ฐฐํฌํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ถ”๊ฐ€ ๊ฐ€๋Šฅ:
# ์˜ˆ์‹œ: ์ด์ „ ๋ฒ„์ „์œผ๋กœ ๋กค๋ฐฑ
IMAGE_TAG=prod-1.0.1

docker pull 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/careerbee-be:$IMAGE_TAG
docker tag 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/careerbee-be:$IMAGE_TAG careerbee-be:rollback
docker-compose down && docker-compose up -d
  • ๋˜๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์ง์ ‘ ์‹คํ–‰ ๋ฐฉ์‹๋„ ๊ฐ€๋Šฅ:
docker stop careerbee-be # ๋ฐฑ์—”๋“œ ์„œ๋ฒ„ ์ข…๋ฃŒ
docker rm careerbee-be
docker run -d --name careerbee-be -p 8080:8080 careerbee-be:rollback
  • Discord๋‚˜ GitHub Actions ์ฃผ์„์„ ํ†ตํ•ด ๋กค๋ฐฑ ์‹œ์ ๊ณผ ์ปค๋ฐ‹ ์ •๋ณด๋ฅผ ์ž๋™ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑ

๐Ÿ“‹ ๊ธฐ์ˆ  ๊ตฌ์„ฑ ๋ช…์„ธ

ํ•ญ๋ชฉ ๋‚ด์šฉ
์ปจํ…Œ์ด๋„ˆ ์ˆ˜ ์ด 4๊ฐœ AWS: 2๊ฐœ (FE, BE) / GCP: 2๊ฐœ(FastAPI, ChromaDB)
๋ฐฐํฌ ๋ฐฉ์‹ ์ธ์Šคํ„ด์Šค ๋‚ด๋ถ€ Docker Compose ๊ธฐ๋ฐ˜ ๋ฐฐํฌ
๋ฒ ์ด์Šค ์ด๋ฏธ์ง€ FE: node:18-alpine, BE: openjdk:17-alpine, AI: python:3.11
์ฃผ์š” Dockerfile ์„ค์ • WORKDIR, COPY, RUN, CMD ๋ฐ healthcheck ๋“ฑ ํฌํ•จ
ํฌํŠธ ์„ค์ • FE: 80/443, BE: 8080, AI: 8000
ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ด€๋ฆฌ .env ํŒŒ์ผ ๋˜๋Š” docker-compose.yml ๋‚ด environment: ๋ธ”๋ก ํ™œ์šฉ
๋กœ๊ทธ ์ €์žฅ volumes:๋กœ ์ธ์Šคํ„ด์Šค ๋กœ์ปฌ์— ๋กœ๊ทธ ํŒŒ์ผ ๋งˆ์šดํŠธ
Docker ๋„คํŠธ์›Œํฌ ๊ตฌ์„ฑ AWS: bridge ๊ธฐ๋ฐ˜ ์ปค์Šคํ…€ ๋„คํŠธ์›Œํฌ(app-net) ๊ตฌ์„ฑ
GCP: FastAPI โ†” ChromaDB ๊ฐ„ ai-net ์‚ฌ์šฉ์ž ์ •์˜ ๋„คํŠธ์›Œํฌ ์ง€์ • โ†’ ๋‚ด๋ถ€ DNS๋กœ ์„œ๋น„์Šค๋ช… ๊ธฐ๋ฐ˜ ํ†ต์‹  ๊ฐ€๋Šฅ

๐Ÿงพ Docker Compose ํŒŒ์ผ ์˜ˆ์‹œ

  • AWS - docker-compose.yml

    version: '3.8'
    services:
      nginx:
        image: nginx:alpine
        ports:
          - "80:80"
        volumes:
          - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
          - ./frontend/dist:/usr/share/nginx/html:ro
        depends_on:
          - frontend
        networks:
          - app-net
      frontend:
        image: 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/careerbee-fe:prod-1.0.0
        ports:
          - "80:80"
        restart: always
        networks:
          - app-net
    
      backend:
        image: 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com/careerbee-be:prod-1.0.0
        ports:
          - "8080:8080"
        restart: always
        environment:
          - SPRING_PROFILES_ACTIVE=prod
          - DB_HOST= MYSQL
        networks:
          - app-net
    
    networks:
      app-net:
        driver: bridge
  • GCP - docker-compose.yml

    version: '3.8'
    services:
      ai:
        image: gcr.io/careerbee-ai/fastapi:prod-1.0.0
        ports:
          - "8000:8000"
        restart: always
        environment:
          - MODEL_PATH=/models/careerbee_model.pt
          - API_KEY=${AI_API_KEY}
        networks:
          - ai-net
    
      chromadb:
        image: chromadb/chroma:latest
        ports:
          - "8001:8000"
        volumes:
          - chroma-data:/chroma/.chroma/index
        networks:
          - ai-net
    
    networks:
      ai-net:
        driver: bridge
    
    volumes:
      chroma-data:

๐Ÿ“‚ Dockerfile ์˜ˆ์‹œ

โœ… FE (Next.js + Vite)

FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install && npm run build
CMD ["npx", "serve", "-s", "dist"]

โœ… BE (Spring Boot)

FROM openjdk:17-alpine
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

โœ… AI (FastAPI)

FROM python:3.11
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir -r requirements.txt
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

๐Ÿ‘ท๐Ÿปโ€โ™‚๏ธ Docker ์ปจํ…Œ์ด๋„ˆ ํ™˜๊ฒฝ์˜ CI/CD

๐Ÿ“Œ ๊ธฐ์กด์—๋„ Self-hosted Runner ๊ธฐ๋ฐ˜์˜ CI/CD๊ฐ€ ๊ตฌ์ถ•๋˜์–ด ์žˆ์—ˆ์œผ๋‚˜, Docker ๊ธฐ๋ฐ˜ CI/CD๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ ์—์„œ ์ฐจ๋ณ„์ ์ธ ๊ฐœ์„  ํšจ๊ณผ๊ฐ€ ๊ธฐ๋Œ€๋œ๋‹ค:

  • CI/CD์˜ ๋ฐฐํฌ ์ผ๊ด€์„ฑ ํ–ฅ์ƒ: ์ด์ „์—๋Š” ์„œ๋ฒ„์— ์ง์ ‘ ๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ฉฐ .jar, ์ •์  ๋ฆฌ์†Œ์Šค, Python ๊ฐ€์ƒํ™˜๊ฒฝ ๋“ฑ์„ ์ˆ˜๋™์œผ๋กœ ์ œ์–ดํ•ด์•ผ ํ–ˆ์œผ๋‚˜, Docker ๊ธฐ๋ฐ˜์—์„œ๋Š” ์ปจํ…Œ์ด๋„ˆ ๋‹จ์œ„๋กœ ํ†ต์ผ๋œ ๋ฐฐํฌ ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Œ
  • ์˜์กด์„ฑ ์„ค์น˜ ๋ถˆํ•„์š”: ๊ธฐ์กด์—๋Š” ๋ฐฑ์—”๋“œ/AI ์„œ๋ฒ„์—์„œ ๊ฐ๊ฐ Java/Python ์˜์กด์„ฑ์„ ์„ค์น˜ํ•˜๊ณ  ์‹คํ–‰ ํ™˜๊ฒฝ์„ ์„ค์ •ํ–ˆ์ง€๋งŒ, Docker ์ด๋ฏธ์ง€๋Š” ๋นŒ๋“œ์‹œ ์ด๋ฏธ ๋ชจ๋“  ํ™˜๊ฒฝ์ด ํฌํ•จ๋˜๋ฏ€๋กœ pull๊ณผ run๋งŒ์œผ๋กœ ์‹คํ–‰๋จ
  • ๋ฌด์ค‘๋‹จ ๋ฐฐํฌ ๋ฐ ๋กค๋ฐฑ: ์ด๋ฏธ์ง€ ๋‹จ์œ„ ๋ฐฐํฌ์ด๋ฏ€๋กœ ์„œ๋น„์Šค ์ค‘๋‹จ ์—†์ด ๋น ๋ฅด๊ฒŒ ์žฌ๋ฐฐํฌ ๋ฐ ๋กค๋ฐฑ ๊ฐ€๋Šฅ
  • ์šด์˜ ์„œ๋ฒ„ ์ธก ์ž๋™ํ™” ์šฉ์ด์„ฑ: docker-compose pull && up -d ๋ช…๋ น์œผ๋กœ ์ „์ฒด ์„œ๋น„์Šค ์ผ๊ด„ ๊ฐฑ์‹  ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์ด๋ฅผ Webhook ๋˜๋Š” SSH ์ž๋™ํ™”๋กœ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Œ

๐Ÿ”„ CI/CD ํ†ตํ•ฉ ํ๋ฆ„๋„

[1] GitHub Push or PR ๋ฐœ์ƒ
        โ†“
[2] GitHub Actions ์‹คํ–‰
    - ๋นŒ๋“œ (FE/BE/AI)
    - ํ…Œ์ŠคํŠธ ๋ฐ Lint
    - ECR์— Docker ์ด๋ฏธ์ง€ Push
        โ†“
[3] Discord ์•Œ๋ฆผ ์ „์†ก
    - ์ƒํƒœ: ์„ฑ๊ณต/์‹คํŒจ
    - ์ปค๋ฐ‹, ์ž‘์„ฑ์ž, ๋นŒ๋“œ ์†Œ์š” ์‹œ๊ฐ„ ๋“ฑ ํฌํ•จ
        โ†“
[4] ์šด์˜ ์„œ๋ฒ„(EC2/GCP) ์ ‘์†
    - docker-compose pull
    - docker-compose up -d
        โ†“
[5] ๋ฐฐํฌ ์™„๋ฃŒ ๋ฐ ๋กœ๊ทธ ํ™•์ธ
    - docker ps
    - docker logs

๐Ÿ”” Discord ์—ฐ๋™์„ ํ†ตํ•œ CI/CD ์•Œ๋ฆผ ์„ค์ •

  • Discord ์—ฐ๋™ ๋ชฉ์ : ๋ฐฐํฌ ์„ฑ๊ณต/์‹คํŒจ ์—ฌ๋ถ€, ์ปค๋ฐ‹ ์ •๋ณด, ๋นŒ๋“œ ์‹œ๊ฐ„ ๋“ฑ์„ Discord๋กœ ์ „๋‹ฌํ•˜์—ฌ ์‹ค์‹œ๊ฐ„ ๋Œ€์‘ ๊ฐ€๋Šฅ
  • ์ ์šฉ ์œ„์น˜: GitHub Actions ๋‚ด ์›Œํฌํ”Œ๋กœ์šฐ ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„์— ์‚ฝ์ž…

๐Ÿ ์Šคํฌ๋ฆฝํŠธ ์˜ˆ์‹œ(GitHub Actions)

name: CI/CD Pipeline

on:
  push:
    branches:
      - main
      - dev
          
  pull_request:
    branches:
      - main
      - dev
          

env:
  ECR_REGISTRY: 123456789012.dkr.ecr.ap-northeast-2.amazonaws.com
  SLACK_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Login to Amazon ECR
        uses: aws-actions/amazon-ecr-login@v1

      - name: Build and Push FE Image
        run: |
          docker build -t $ECR_REGISTRY/careerbee-fe:prod-1.0.0 ./frontend
          docker push $ECR_REGISTRY/careerbee-fe:prod-1.0.0

      - name: Build and Push BE Image
        run: |
          docker build -t $ECR_REGISTRY/careerbee-be:prod-1.0.0 ./backend
          docker push $ECR_REGISTRY/careerbee-be:prod-1.0.0

      - name: Build and Push AI Image
        run: |
          docker build -t $ECR_REGISTRY/careerbee-ai:prod-1.0.0 ./ai
          docker push $ECR_REGISTRY/careerbee-ai:prod-1.0.0

      - name: Notify to Discord
        if: always()
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          fields: repo,message,commit,author,job,took
        env:
          DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}

์šด์˜ ๋ฐฐํฌ ์‹œ์ ๊ณผ ์—ฐ๋™ํ•˜์—ฌ Discord ์ฑ„๋„๋กœ ๋น ๋ฅด๊ฒŒ ์•Œ๋ฆผ์ด ๊ฐ€๋ฏ€๋กœ, ์žฅ์•  ๋Œ€์‘ ์‹œ๊ฐ„ ์ตœ์†Œํ™” ๋ฐ ๋ฐฐํฌ ์Šน์ธ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์— ์šฉ์ดํ•จ

โš™๏ธ ๋ฐฐํฌ ํ”Œ๋กœ์šฐ ์š”์•ฝ

  • GitHub Actions:
    • ๋ธŒ๋žœ์น˜ ๋˜๋Š” PR ๊ธฐ์ค€ ์ž๋™ ๋นŒ๋“œ โ†’ ECR์— ์ด๋ฏธ์ง€ Push
    • ํƒœ๊ทธ ์ „๋žต ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฒ„์ „ ๊ตฌ๋ถ„ (์˜ˆ: prod-1.2.3)
  • EC2 ์„œ๋ฒ„:
    • docker-compose pull โ†’ docker-compose up -d

    • ๋ณ€๊ฒฝ๋œ ์„œ๋น„์Šค๋งŒ ์ด๋ฏธ์ง€ ๊ฐฑ์‹  ๊ฐ€๋Šฅ (๋ฌด์ค‘๋‹จ ๋ฐฐํฌ ๊ธฐ๋ฐ˜)

      ๊ตฌ๋ถ„ docker pull docker-compose pull
      ๋Œ€์ƒ ๊ฐœ๋ณ„ ์ด๋ฏธ์ง€ ์ง€์ • ํ•„์š” docker-compose.yml์— ์ •์˜๋œ ๋ชจ๋“  ์„œ๋น„์Šค์˜ ์ด๋ฏธ์ง€๋ฅผ ํ•œ ๋ฒˆ์—
      ์‚ฌ์šฉ ์œ„์น˜ ํ„ฐ๋ฏธ๋„์—์„œ ์ง์ ‘ Docker Compose ๊ธฐ๋ฐ˜ ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ
      ์˜ˆ์‹œ docker pull nginx:latest docker-compose pull
      ์žฅ์  ํŠน์ • ์ด๋ฏธ์ง€๋งŒ ๋น ๋ฅด๊ฒŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Œ ๋‹ค์ˆ˜์˜ ์ปจํ…Œ์ด๋„ˆ ์„œ๋น„์Šค๋ฅผ ๋™์‹œ์— ์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅ
      ํ™œ์šฉ ์‹œ์  ์ˆ˜๋™ ์—…๋ฐ์ดํŠธ, ๊ฐœ๋ณ„ ํ…Œ์ŠคํŠธ CI/CD ๋˜๋Š” ์šด์˜ ํ™˜๊ฒฝ์—์„œ์˜ ์ „์ฒด ์„œ๋น„์Šค ์—…๋ฐ์ดํŠธ ์‹œ

๐Ÿ’ฐ ๋น„์šฉ ์˜ˆ์ธก

๊ตฌ์„ฑ ์š”์†Œ ์˜ˆ์ƒ ๋น„์šฉ (์›”๊ฐ„) ์„ค๋ช…
EC2 t3.medium (FE/BE) X 2 ์•ฝ $30~35 ์„œ์šธ ๋ฆฌ์ „ ๊ธฐ์ค€, ์˜จ๋””๋งจ๋“œ ์š”๊ธˆ + EBS ํฌํ•จ
EC2 t3.micro (VPN) ์•ฝ $5 ๊ฐœ๋ฐœ์ž ์ „์šฉ VPN ์„œ๋ฒ„, ํŠธ๋ž˜ํ”ฝ ๋‚ฎ์Œ
EC2 t3.micro (Database) X 2 ์•ฝ $10 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(MySQL) ์„œ๋ฒ„
ECR ์Šคํ† ๋ฆฌ์ง€ ์•ฝ $3 ์ด๋ฏธ์ง€ ์ €์žฅ๋Ÿ‰์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง (GB๋‹น ์š”๊ธˆ ์ ์šฉ)
S3 (์ •์  ๋ฆฌ์†Œ์Šค ์ €์žฅ) ์•ฝ $1~3 ์ €์žฅ ๋ฐ ํŠธ๋ž˜ํ”ฝ ์–‘์— ๋”ฐ๋ผ ์œ ๋™์ 
Route53 ๋„๋ฉ”์ธ + ํ˜ธ์ŠคํŒ… ์กด ์•ฝ $2 1 ๋„๋ฉ”์ธ ๊ธฐ์ค€
GCP GCE Standard (AI ์„œ๋ฒ„) ์•ฝ $30~40 e2-medium ๊ธฐ์ค€, Chroma + FastAPI ์ปจํ…Œ์ด๋„ˆ ์šด์˜
GCP GPU ์ธ์Šคํ„ด์Šค ์•ฝ $167 g2-standard-8(vCPUs: 8, RAM: 32 GiB, GPUs: 1) ๊ธฐ์ค€, ๋ชจ๋ธ ์ถ”๋ก  ์„œ๋ฒ„
NAT Gateway ์•ฝ $40 ์‹œ๊ฐ„๋‹น $0.065 + GB๋‹น $0.09 ํŠธ๋ž˜ํ”ฝ ์š”๊ธˆ ๋ฐœ์ƒ (๊ธฐ๋ณธ ์š”๊ธˆ ๊ธฐ์ค€)

๐Ÿ’ก ์˜ˆ์ƒ ์ดํ•ฉ (์›”): ์•ฝ $300 ์ˆ˜์ค€(์ฃผ 45์‹œ๊ฐ„ ์šด์˜ ๊ธฐ์ค€)


๐Ÿ“Œ ๋ณธ ํŽ˜์ด์ง€๋Š” 2025๋…„ 5์›” 26์ผ์— ๋งˆ์ง€๋ง‰์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ