Docker - 100-hours-a-week/3-team-ssammu-wiki GitHub Wiki
-
VPC (SSMU-DEV)
- CIDR:
192.168.0.0/16
- CIDR:
-
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.medium
2๋ ์ฌ์ฉ(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
๋ช ๋ น์ผ๋ก ๋ฐฐํฌ ์ํ
-
VPC (SSMU-AI)
- CIDR:
10.0.0.0/16
- CIDR:
-
Public Subnet (SUBNET-SSMU-AI-PUBLIC)
- CIDR:
10.0.10.0/24
- CIDR:
-
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 ํ๊ฒฝ์ผ๋ก์ ์ ํ๋ ์ ์ฐํ๊ฒ ๋์ ๊ฐ๋ฅ
-
ํ์ฌ ์ฐ๋ฆฌ ์๋น์ค๋ ์คํ๋ฆฐํธ ๊ธฐ๊ฐ ๋ด ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ ์ ๋ฐ์ดํธ๊ฐ ์์ ๋์ด ์์ผ๋ฉฐ, ๊ฐ๊ฐ์ ๊ธฐ๋ฅ์ด ์์ ์ ์ด๊ณ ๋ ๋ฆฝ์ ์ผ๋ก ์ด์๋์ด์ผ ํ๋ค:
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 ๋ฐฐํฌ (๊ธฐ์กด) | 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 ์๋ฒ๋ง ์์ ํ์ ๋ ์ ์ฒด ์ฌ๋ฐฐํฌ๊ฐ ํ์ ์์ด ํด๋น ์ปจํ ์ด๋๋ง ์ฌ์คํ
ํญ๋ชฉ | 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: ์ ์ฒด ์ธ์คํด์ค๋ฅผ ์์ฐจ์ ์ผ๋ก ๊ต์ฒดํ๋ ๋ฐฉ์. ํธ๋ํฝ์ ํญ์ ์ผ๋ถ ์ธ์คํด์ค๋ฅผ ํตํด ์ ์ง๋๋ฏ๋ก ๋ค์ดํ์์ด ๊ฑฐ์ ์์
- Blue-Green Deployment: ํ์ฌ ์ด์ ์ค์ธ ๋ฒ์ (Blue)๊ณผ ์ ๊ท ๋ฐฐํฌ ๋ฒ์ (Green)์ ๋ณ๋ ฌ๋ก ์ ์งํ ๋ค, ํธ๋ํฝ์ Green์ผ๋ก ์ ํํ๋ ๋ฐฉ์. ์ฅ์ ๋ฐ์ ์ Blue๋ก ๋กค๋ฐฑ ๊ฐ๋ฅ
์ ๋ต | ์ฅ์ | ๋จ์ | ์ฐ๋ฆฌ ์๋น์ค์์ ์ ํฉ์ฑ |
---|---|---|---|
Rolling Update | ์ ์ง์ ์ ๋ฐ์ดํธ - ๋ค์ดํ์ ์ต์ํ - ์์ ํจ์จ์ | ์ค๊ฐ ๋จ๊ณ์์ ์ค๋ฅ ๋ฐ์ ์ ๋กค๋ฐฑ ์ด๋ ค์ | - ๋น ๋ฅด๊ฒ ์ฑ์ฅํ๋ฉฐ ๊ธฐ๋ฅ์ด ์์ฃผ ์ถ๊ฐ๋๋ ์ฐ๋ฆฌ ์๋น์ค ๊ฐ๋ฐ ํ๋ฆ์ ์ ํฉ - ์คํ์ ๊ธฐ๋ฅ ์ถ๊ฐ ์ ์ ์ฐํ๊ฒ ๋์ ๊ฐ๋ฅ |
Blue-Green Deployment | ์์ ํ ์ด์ ๋ฒ์ ๋ณด์กด - ๋ฐฐํฌ ์คํจ ์ ์์ฌ์ด ๋กค๋ฐฑ ๊ฐ๋ฅ | ์์ ๋ ๋ฐฐ ์ฌ์ฉ | - ๋ฆฌ์์ค ์ ์ฝ์ด ์๋ ํ์ฌ ๊ตฌ์กฐ์์๋ ๋ค์ ๋ถ๋ด - EC2, GCE ๊ธฐ๋ฐ ๋ฐฐํฌ ๊ตฌ์กฐ์ ์ ๋ง์ง ์์ |
๐น ๋ฐ๋ผ์ Rolling Update ์ ๋ต์ ์ฐ์ ์ ์ฉํ๊ณ , ์ต์ข ์ ์ผ๋ก Kubernetes ํ๊ฒฝ์ผ๋ก ์ ํ ์ Helm ๋๋ ArgoCD ๊ธฐ๋ฅ์ ํตํ Blue-Green ์ ๋ต์ ํ์ผ ๋ถ๊ฐ์ ์ผ๋ก ๊ณ ๋ คํ๋ค.
- ๊ฐ ๋น๋ ์์ ๋ง๋ค
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๋ก ์๋น์ค๋ช
๊ธฐ๋ฐ ํต์ ๊ฐ๋ฅ |
-
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:
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install && npm run build
CMD ["npx", "serve", "-s", "dist"]
FROM openjdk:17-alpine
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
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"]
๐ ๊ธฐ์กด์๋ 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 ์๋ํ๋ก ์ฐ๊ฒฐํ ์ ์์
[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 ์ฐ๋ ๋ชฉ์ : ๋ฐฐํฌ ์ฑ๊ณต/์คํจ ์ฌ๋ถ, ์ปค๋ฐ ์ ๋ณด, ๋น๋ ์๊ฐ ๋ฑ์ Discord๋ก ์ ๋ฌํ์ฌ ์ค์๊ฐ ๋์ ๊ฐ๋ฅ
- ์ ์ฉ ์์น: 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์ผ์ ๋ง์ง๋ง์ผ๋ก ์ ๋ฐ์ดํธ๋์์ต๋๋ค.