Docker - 100-hours-a-week/21-iceT-wiki GitHub Wiki

4๋‹จ๊ณ„: Docker ์ปจํ…Œ์ด๋„ˆํ™” ๋ฐฐํฌ

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

Docker ๋„์ž… ํ›„ ์„œ๋น„์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.
๊ฐ ํ™˜๊ฒฝ์€ ๋™์ผํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์œผ๋ฉฐ, Dev ํ™˜๊ฒฝ์€ ํ…Œ์ŠคํŠธ ๋ฐ ๊ฒ€์ฆ์šฉ, Prod ํ™˜๊ฒฝ์€ ์‹ค์ œ ์„œ๋น„์Šค ์‚ฌ์šฉ์ž ๋Œ€์ƒ์ž…๋‹ˆ๋‹ค.

Docker ๋„์ž… ๊ฒฐ์ • ๋ฐ ๋ฒ”์œ„

1. ๋„์ž… ๋ฐฐ๊ฒฝ (์™œ Docker๋ฅผ ๋„์ž…ํ–ˆ๋Š”๊ฐ€?)

์šฐ๋ฆฌ ์„œ๋น„์Šค๋Š” ๋‹จ์ผ EC2 ์ธ์Šคํ„ด์Šค์—์„œ React(ํ”„๋ก ํŠธ์—”๋“œ), Spring Boot(๋ฐฑ์—”๋“œ), MySQL(DB)๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์œผ๋ฉฐ, ๊นƒํ—ˆ๋ธŒ์—์„œ git clone์œผ๋กœ EC2๋กœ ๋ฐ›์•„์˜ค๋Š” ๋ฐฉ์‹์œผ๋กœ ์ˆ˜๋™ ๋ฐฐํฌ๋ฅผ ์ง„ํ–‰ํ•ด ์™”์Šต๋‹ˆ๋‹ค. ์ดํ›„ GitHub Actions ๊ธฐ๋ฐ˜์˜ CI/CD ํŒŒ์ดํ”„๋ผ์ธ์„ ๋„์ž…ํ•˜๋ฉฐ ์ž๋™ํ™” ์ˆ˜์ค€์„ ๋†’์˜€์ง€๋งŒ, ์—ฌ์ „ํžˆ ๊ฐ ์„œ๋น„์Šค๊ฐ€ ๋™์ผํ•œ EC2 OS ๋‚ด์—์„œ ์‹คํ–‰๋จ์— ๋”ฐ๋ผ ํ™˜๊ฒฝ ์ถฉ๋Œ, ํ™•์žฅ์„ฑ ๋ถ€์กฑ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ, Docker๋ฅผ ๋„์ž…ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•œ ์ด์œ ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค:


2. ๋„์ž… ๋ชฉ์ 

์ด์œ  ๋ถ€๊ฐ€ ์„ค๋ช…
ํ™˜๊ฒฝ ๋ถˆ์ผ์น˜ ํ•ด๊ฒฐ - ๊ฐœ๋ฐœ์ž๋งˆ๋‹ค ์–ธ์–ด ๋ฒ„์ „ ๋˜๋Š” OS ํ™˜๊ฒฝ์ด ๋‹ฌ๋ผ ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ, ์˜์กด์„ฑ ์ถฉ๋Œ ๋“ฑ ๋ฐœ์ƒ - Docker ์ด๋ฏธ์ง€๋กœ ํ†ต์ผ๋œ ์‹คํ–‰ ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•˜์—ฌ ๋กœ์ปฌ์—์„  ๋˜๋Š”๋ฐ, ์„œ๋ฒ„์—์„  ์•ˆ ๋˜๋Š” ๋ฌธ์ œ ํ•ด์†Œ
์„œ๋น„์Šค ๊ฐ„ ๊ฐ„์„ญ ๋ฐฉ์ง€ - ๋ชจ๋“  ๊ตฌ์„ฑ์š”์†Œ๊ฐ€ ๋™์ผํ•œ OS ๋‚ด์—์„œ ์‹คํ–‰๋  ๊ฒฝ์šฐ ์˜์กด์„ฑ ์ถฉ๋Œ, ํฌํŠธ ์ถฉ๋Œ ๋ฐœ์ƒ ์œ„ํ—˜ - ์ปจํ…Œ์ด๋„ˆ๋กœ ๊ฒฉ๋ฆฌํ•˜์—ฌ ์ถฉ๋Œ ์—†์ด ๋…๋ฆฝ์  ์‹คํ–‰ ๊ฐ€๋Šฅ
ํ™•์žฅ์„ฑ ๋ถ€์กฑ ํ•ด์†Œ - ํ˜„์žฌ๋Š” ๋‹จ์ผ ์ธ์Šคํ„ด์Šค์— ์„œ๋น„์Šค๊ฐ€ ์ง์ ‘ ์˜ฌ๋ผ๊ฐ€ ์žˆ์–ด ์ˆ˜ํ‰ ํ™•์žฅ ์–ด๋ ค์›€ - Docker ๊ธฐ๋ฐ˜์œผ๋กœ ์„œ๋น„์Šค ๋‹จ์œ„ ์ปจํ…Œ์ด๋„ˆํ™”ํ•˜์—ฌ ํ–ฅํ›„ ๋ถ„์‚ฐ ์šด์˜ ๊ตฌ์กฐ๋กœ ์ „ํ™˜์„ ์œ„ํ•œ ๋ฐœํŒ ๋งˆ๋ จ
๋ณต๊ตฌ ๋ฐ ์ด์ „ ๋น„์šฉ ์ ˆ๊ฐ - Docker ์ด๋ฏธ์ง€ ์žฌ๋ฐฐํฌ๋งŒ์œผ๋กœ ์ธํ”„๋ผ ๋ณ€๊ฒฝ ์‹œ์—๋„ ๋™์ผ ์„œ๋น„์Šค ์žฌํ˜„ ๊ฐ€๋Šฅ
๋ฒ„์ „ ๊ด€๋ฆฌ ์šฉ์ด - Dockerfile ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐ ๋ฒ„์ „์„ ๋ช…ํ™•ํ•˜๊ฒŒ ํƒœ๊น… ๊ฐ€๋Šฅ - ํƒœ๊น…์œผ๋กœ ์ด์ „ ์ด๋ฏธ์ง€๋กœ ์‰ฝ๊ฒŒ ๋กค๋ฐฑ ๊ฐ€๋Šฅ (release-v2.0.0 -> release-v1.0.0)
Blue-Green ๋ฐฐํฌ ๊ตฌ์กฐ ์ „ํ™˜ ์šฉ์ด - ์ปจํ…Œ์ด๋„ˆ ๋‹จ์œ„๋กœ ํฌํŠธ๋ฅผ ๋ฐ”๊ฟ”๊ฐ€๋ฉฐ ํŠธ๋ž˜ํ”ฝ ์ „ํ™˜ ๊ฐ€๋Šฅ - ์‹คํ–‰ ์ค‘์ธ ์ธ์Šคํ„ด์Šค๋Š” ๊ทธ๋Œ€๋กœ ๋‘๊ณ  ์ปจํ…Œ์ด๋„ˆ๋งŒ ๊ต์ฒดํ•˜์—ฌ ์„œ๋น„์Šค ์ „ํ™˜ ๊ฐ„์†Œํ™”
Terraform ์—ฐ๊ณ„ ๊ฐ€๋Šฅ์„ฑ ํ™•๋ณด - ์ธํ”„๋ผ๋Š” Terraform์œผ๋กœ ๊ณ ์ •ํ•œ ์ฑ„, Docker๋กœ ์„œ๋น„์Šค๋งŒ ์œ ์—ฐํ•˜๊ฒŒ ์ „ํ™˜ ๊ฐ€๋Šฅ - IaC(Terraform) + ์ปจํ…Œ์ด๋„ˆ ๋ฐฐํฌ ์ „๋žต์˜ ํ†ตํ•ฉ ๊ด€๋ฆฌ ๊ธฐ๋ฐ˜ ๋งˆ๋ จ

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

Docker๋ฅผ ๋„์ž…ํ•˜์—ฌ ์„œ๋น„์Šค ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ถ„๋ฆฌ๋œ ์ปจํ…Œ์ด๋„ˆ๋กœ ๊ด€๋ฆฌํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค:

  • React ํ”„๋ก ํŠธ์—”๋“œ โ†’ Nginx ๊ธฐ๋ฐ˜ ์ •์  ํŒŒ์ผ ์„œ๋น™ ์ปจํ…Œ์ด๋„ˆ

  • Spring Boot ๋ฐฑ์—”๋“œ โ†’ JDK ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…Œ์ด๋„ˆ

  • FastAPI(AI) โ†’ Python ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…Œ์ด๋„ˆ

  • MySQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค โ†’ MYSQL ์ปจํ…Œ์ด๋„ˆ๋กœ ์‚ฌ์šฉ


4. ๋„์ž… ์‹œ ์˜ˆ์ƒ๋˜๋Š” ๋ณ€ํ™”

  • ๋ฐฐํฌ ํšจ์œจ์„ฑ ํ–ฅ์ƒ: ์ด๋ฏธ์ง€ ๋นŒ๋“œ ๋ฐ ํ‘ธ์‹œ ํ›„ ๊ฐ„๋‹จํ•œ pull & run์œผ๋กœ ๋ฐฐํฌ ์ž๋™ํ™”

  • ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ํ†ต์ผ: ๋™์ผํ•œ Docker ์ด๋ฏธ์ง€๋กœ QA ํ…Œ์ŠคํŠธ ๋ฐ ๋กœ์ปฌ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ

  • ๋ฒ„์ „ ๊ด€๋ฆฌ ๋ช…ํ™•ํ™”: ๊ฐ ์„œ๋น„์Šค๋ณ„ Dockerfile ๋ฐ ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋ฅผ ํ†ตํ•ด ๋ฆด๋ฆฌ์ฆˆ ๊ด€๋ฆฌ ์šฉ์ด

  • ์žฅ๊ธฐ์ ์œผ๋กœ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ๊ฐ€๋Šฅ์„ฑ ํ™•๋ณด: Docker Compose ๋ฐ ์ถ”ํ›„ Kubernetes์™€์˜ ์—ฐ๊ณ„ ์‹œ ์šฉ์ด


์ปจํ…Œ์ด๋„ˆ ๋ฐฐํฌ ์ „๋žต

1. Docker ๋„์ž… ์ „๋žต ์„ค๋ช…์„œ

๋นŒ๋“œ ๋ฐฉ์‹

์„œ๋น„์Šค๋ณ„๋กœ ๋…๋ฆฝ๋œ Dockerfile์„ ์ž‘์„ฑํ•˜์—ฌ GitHub Actions์—์„œ ์ด๋ฏธ์ง€ ๋นŒ๋“œ ์ž๋™ํ™”

  • React: ์ •์  ํŒŒ์ผ ๋นŒ๋“œ ํ›„ Nginx์— ํฌํ•จ

  • Spring Boot: JAR ํŒŒ์ผ์„ ํฌํ•จํ•œ OpenJDK ๊ธฐ๋ฐ˜ ์ด๋ฏธ์ง€

  • FastAPI: Python ํ™˜๊ฒฝ ๊ธฐ๋ฐ˜์œผ๋กœ requirements.txt ์„ค์น˜ ํ›„ Uvicorn ์‹คํ–‰ ์ด๋ฏธ์ง€


์ด๋ฏธ์ง€ ํƒœ๊น… ์ „๋žต

  • latest
    • ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ์œ ์šฉ
    • ํ•ญ์ƒ ์ตœ์‹  ๋ฒ„์ „์„ ๊ฐ€๋ฆฌํ‚ด
    • ๊ฐ€์žฅ ์ตœ๊ทผ์— ๋นŒ๋“œ๋œ ์ด๋ฏธ์ง€
  • v1.0.0
    • ๋ช…์‹œ์  ๋ฒ„์ „ ๊ด€๋ฆฌ
    • ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ ์œ ์šฉ

์ตœ์ข… ์„ ํƒ: ์šด์˜ ํ™˜๊ฒฝ์€ v1.0.0 ํƒœ๊ทธ ๊ธฐ๋ฐ˜ ๋ฐฐํฌ, ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์€ latest ํ™œ์šฉ


Docker ๋„์ž… ํ›„ CI/CD ์ˆœ์„œ

  1. GitHub Actions์—์„œ ์ฝ”๋“œ ํ‘ธ์‹œ ๊ฐ์ง€

    • ๋ธŒ๋žœ์น˜ ํ‘ธ์‹œ ๋˜๋Š” PR ๋ณ‘ํ•ฉ ๋ฐœ์ƒ ์‹œ ์›Œํฌํ”Œ๋กœ์šฐ ํŠธ๋ฆฌ๊ฑฐ
  2. ์ฝ”๋“œ ๋นŒ๋“œ (Dockerfile)

    • Spring Boot๋Š” ./gradlew build๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ .jar ์ƒ์„ฑ
    • React๋Š” npm run build๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ build ํด๋” ์ƒ์„ฑ
    • FAST API๋Š” requirements.txt๋ฅผ ์„ค์น˜
  3. Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ

    • docker build -t my-app:release-v1.0.0 .

      -> ์„œ๋น„์Šค๋ณ„๋กœ ์ด๋ฏธ์ง€ ๊ฐ๊ฐ ๋นŒ๋“œ (ํ”„๋ก ํŠธ, ๋ฐฑ์—”๋“œ๋“ฑ)

  4. ์ด๋ฏธ์ง€ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ํ‘ธ์‹œ(ECR)

    • docker push my-app:release-v1.0.0

      โ†’ DockerHub์— ํ‘ธ์‹œ

  5. AWS CodeDeploy๋ฅผ ํ†ตํ•ด EC2์— ๋ฐฐํฌ

    • CodeDeploy๊ฐ€ ์ด๋ฏธ์ง€๊ฐ€ ํ‘ธ์‹œ๋œ ๊ฒƒ์„ ๊ฐ์ง€ํ•˜๊ณ  EC2 ์ธ์Šคํ„ด์Šค์— ๋ฐฐํฌ ์ˆ˜ํ–‰
    • AppSpec ํŒŒ์ผ(appspec.yml)์„ ํ†ตํ•ด ์ปจํ…Œ์ด๋„ˆ pull, stop, run ๋‹จ๊ณ„ ์ž๋™ํ™”

์ด๋ฏธ์ง€ ์ €์žฅ์†Œ

  • ECR ์‚ฌ์šฉ

์ปจํ…Œ์ด๋„ˆ ๊ฐ„ ์—ฐ๋™ ๋ฐฉ์‹

  • ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ๋Š” ๋™์ผํ•œ ๋ธŒ๋ฆฟ์ง€ ๋„คํŠธ์›Œํฌ (app-network) ์ƒ์— ์กด์žฌ.
  • ์ปจํ…Œ์ด๋„ˆ ๊ฐ„ ํ†ต์‹ ์€ ์„œ๋น„์Šค ์ด๋ฆ„(DNS ์ด๋ฆ„์ฒ˜๋Ÿผ ์ž‘๋™)์œผ๋กœ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ๋ณ„๋„ IP ์„ค์ • ์—†์ด ๋„์ปค ๋‚ด๋ถ€ ๋„คํŠธ์›Œํฌ๋กœ ์ ‘๊ทผ.
  • ๋‚ด๋ถ€ ํฌํŠธ๋Š” ์ปจํ…Œ์ด๋„ˆ ๊ฐ„ ํ†ต์‹ ์šฉ์ด๋ฉฐ, ์™ธ๋ถ€ ํฌํŠธ๋Š” ๋ณด์•ˆ ๊ทธ๋ฃน ๋˜๋Š” ํ”„๋ก์‹œ(Nginx ๋“ฑ)๋กœ ์ œํ•œ.
  • ์˜ˆ๋ฅผ ๋“ค์–ด, React ์•ฑ์—์„œ http://spring:8080์œผ๋กœ Spring Boot์— ์ ‘๊ทผ.

์˜ˆ์‹œ: docker-compose.yml ๋‚ด ์ปจํ…Œ์ด๋„ˆ ์—ฐ๋™

version: '3.8'

services:
  react:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    networks:
      - app-network
    ports:
      - "8080:8080"
    environment:
      - NODE_ENV=development
    depends_on:
      - spring
      - fastapi

  spring:
    build:
      context: ./backend
      dockerfile: Dockerfile
    networks:
      - app-network
    ports:
      - "8001:8001"
    environment:
      - SPRING_PROFILES_ACTIVE=local
      - DB_HOST=db
      - DB_PORT=3306
      - DB_USERNAME=root
      - DB_PASSWORD=secret
    depends_on:
      - db

  fastapi:
    build:
      context: ./ai
      dockerfile: Dockerfile
    networks:
      - app-network
    ports:
      - "8000:8000"

networks:
  app-network:


ํ˜ธ์ŠคํŠธ ๋จธ์‹  ์ž์› ํ• ๋‹น ์ „๋žต

ํ˜„ ์ƒํ™ฉ

ํ˜„์žฌ EC2 ์ธ์Šคํ„ด์Šค๋Š” t3.medium (2 vCPU, 4GB RAM) ์ŠคํŽ™์œผ๋กœ, React + Spring Boot์„ ๋‹จ์ผ ๋จธ์‹ ์—์„œ React์™€ Spring Boot๋ฅผ ์ปจํ…Œ์ด๋„ˆ๋กœ ์šด์˜ํ•  ์˜ˆ์ •. Docker๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ์— ๋ฆฌ์†Œ์Šค ์ œํ•œ์„ ๋‘์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ๊ฐ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๊ณผ๋„ํ•˜๊ฒŒ ์ž์›์„ ์ ์œ ํ•˜์ง€ ์•Š๋„๋ก ๋ช…์‹œ์ ์œผ๋กœ CPU/๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ์„ ์„ค์ •.

ํ˜ธ์ŠคํŠธ ๋จธ์‹  ์ž์› ํ• ๋‹นํ‘œ

์„œ๋น„์Šค ํŠน์„ฑ ์˜ˆ์ƒ ๋ฆฌ์†Œ์Šค ์ œํ•œ ์˜ˆ์‹œ
React (Nginx) ์ •์  ํŒŒ์ผ ์„œ๋น™, ๊ฒฝ๋Ÿ‰ CPU: ๋งค์šฐ ๋‚ฎ์ŒRAM: ๋‚ฎ์Œ cpus: 0.4, memory: 256M
Spring Boot ๋ฉ”์ธ API ์„œ๋ฒ„ CPU: ์ค‘๊ฐ„~๋†’์ŒRAM: ๋†’์Œ cpus: 1.6, memory: 3072M

โ€ป ๋ชจ๋“  ๋ฆฌ์†Œ์Šค๋ฅผ ํ•ฉ์ณ๋„ 2 vCPU, 4GB ์ด๋‚ด๋กœ ๊ตฌ์„ฑํ•ด์•ผ ํ•จ

์ดํ•ฉ: 2.0 vCPU, 3328MB RAM ์‚ฌ์šฉ (์—ฌ์œ ๋ถ„ 768MB ํ™•๋ณด)


๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ์˜ Docker Compose ๊ตฌ์„ฑ

version: "3.8"
services:
  frontend:
    build: ./frontend
    ports:
      - "8080:80"
    volumes:
      - ./frontend:/app
    environment:
      - NODE_ENV=development

  backend:
    build: ./backend
    ports:
      - "8001:8001"
    environment:
      - SPRING_PROFILES_ACTIVE=dev

  ai:
    build: ./ai
    ports:
      - "8000:8000"

๐ŸŽฏ ์šด์˜ ํ™˜๊ฒฝ์—์„œ๋Š”

  • GitHub Actions โ†’ Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ โ†’ ECR ํ‘ธ์‹œ

  • EC2์—์„œ docker pull + docker run์œผ๋กœ ์šด์˜

  • ๋ฆฌ์†Œ์Šค ์ œํ•œ (--memory, --cpus) ์„ค์ • ํ•„์ˆ˜

  • .env ๋Œ€์‹  ์šด์˜ ๋ณ€์ˆ˜๋Š” EC2 ํ™˜๊ฒฝ ๋ณ€์ˆ˜, AWS Secrets Manager, .tfvars ๋“ฑ์œผ๋กœ ๋ถ„๋ฆฌ


๊ณตํ†ต ๊ตฌ์„ฑ ์š”์†Œ (Dev / Prod)

๊ตฌ์„ฑ ์š”์†Œ ์„ค๋ช…
VPC/Subnet ํผ๋ธ”๋ฆญ ๋ฐ ํ”„๋ผ์ด๋น— ์„œ๋ธŒ๋„ท์œผ๋กœ ๋ถ„๋ฆฌ ๊ตฌ์„ฑ (AZ ๋ถ„์‚ฐ)
EC2 (Auto Scaling Group) ํ”„๋ก ํŠธ์—”๋“œ, ๋ฐฑ์—”๋“œ, FastAPI ์•ฑ์ด Docker ์ปจํ…Œ์ด๋„ˆ ํ˜•ํƒœ๋กœ ๋ฐฐํฌ
MySQL (AWS RDS) ์ปจํ…Œ์ด๋„ˆํ™” ์—†์ด AWS์˜ RDS๋ฅผ ์‚ฌ์šฉํ•ด ํ”„๋ผ์ด๋น— ์„œ๋ธŒ๋„ท์—์„œ ์ ‘๊ทผ
Docker + GitHub Actions ๋นŒ๋“œ ๋ฐ ECR ์ด๋ฏธ์ง€ ํ‘ธ์‹œ๋Š” GitHub Actions๋ฅผ ํ†ตํ•ด ์ˆ˜ํ–‰
AWS CodeDeploy ๋ฐฐํฌ๋Š” CodeDeploy๊ฐ€ ๋‹ด๋‹นํ•˜๋ฉฐ, EC2 ์ธ์Šคํ„ด์Šค์—์„œ ์ด๋ฏธ์ง€ pull & ์‹คํ–‰
OpenVPN ์™ธ๋ถ€ ์ ‘๊ทผ ์‹œ ๋ณด์•ˆ ์—ฐ๊ฒฐ ์šฉ๋„
ALB + Route53 ALB๋ฅผ ํ†ตํ•ด ํŠธ๋ž˜ํ”ฝ ๋ถ„์‚ฐ, Route53์œผ๋กœ ์‚ฌ์šฉ์ž ๋„๋ฉ”์ธ ์—ฐ๊ฒฐ ์ฒ˜๋ฆฌ

ํ™˜๊ฒฝ๋ณ„ ์ฐจ์ด

ํ™˜๊ฒฝ ๊ตฌ๋ถ„ ๋ชฉ์  ์ ‘๊ทผ ๋Œ€์ƒ ํŠน์ง•
Dev ๊ฐœ๋ฐœ ๋ฐ ํ…Œ์ŠคํŠธ ๊ฐœ๋ฐœ์ž ์‹ค์ œ ์šด์˜๊ณผ ๋™์ผํ•œ ๊ตฌ์กฐ์—์„œ ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰
Prod ์‹ค ์„œ๋น„์Šค ์šด์˜ ์ตœ์ข… ์‚ฌ์šฉ์ž ์‹ค ํŠธ๋ž˜ํ”ฝ ๋Œ€์‘, ๊ณ ๊ฐ€์šฉ์„ฑ ๊ตฌ์„ฑ ๋ฐ ๋ณด์•ˆ ๊ฐ•ํ™”

์„œ๋น„์Šค ๋‚ด ์ปจํ…Œ์ด๋„ˆ ์—ญํ• 

์ปจํ…Œ์ด๋„ˆ ๊ธฐ๋Šฅ
React (Nginx) ์ •์  ํŒŒ์ผ ์„œ๋น™
Spring Boot ์‚ฌ์šฉ์ž ์ธ์ฆ, ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
FastAPI AI ๋ชจ๋ธ ์ถ”๋ก  ๋ฐ API ์ฒ˜๋ฆฌ

์™ธ๋ถ€ ์—ฐ๋™

  • Docker ์ด๋ฏธ์ง€ ์ €์žฅ์†Œ: AWS ECR
  • CI: GitHub Actions
  • CD: AWS CodeDeploy
  • AI ์„œ๋น„์Šค: FastAPI๋Š” ํผ๋ธ”๋ฆญ ์ธ์Šคํ„ด์Šค์—์„œ ์ง์ ‘ ํ˜ธ์ŠคํŒ…

์ด ๊ตฌ์กฐ๋Š” ํ™˜๊ฒฝ ์ผ๊ด€์„ฑ, ํ™•์žฅ์„ฑ, ๋ณด์•ˆ์„ฑ์„ ๊ณ ๋ คํ•˜์—ฌ ์„ค๊ณ„๋˜์—ˆ์œผ๋ฉฐ, CI/CD ์ž๋™ํ™”์™€ ํด๋ผ์šฐ๋“œ ์ž์› ํ™œ์šฉ์„ ํ†ตํ•ด ์„œ๋น„์Šค ๋ฐฐํฌ ์†๋„์™€ ์•ˆ์ •์„ฑ์„ ํ™•๋ณดํ–ˆ์Šต๋‹ˆ๋‹ค.


2. Docker ๊ธฐ๋ฐ˜ ์„œ๋น„์Šค ๊ธฐ์ˆ  ๋ช…์„ธ

1. React (Static SPA)

  • ๋ฒ ์ด์Šค ์ด๋ฏธ์ง€: node:18-alpine, nginx:stable-alpine
  • ์ปจํ…Œ์ด๋„ˆ ์ˆ˜: 8๊ฐœ (Prod์šฉ, Dev์šฉ 4๊ฐœ, AZ ๋‹น 2๊ฐœ)
  • ์—ญํ• : React ์•ฑ์„ ๋นŒ๋“œํ•˜์—ฌ Nginx๋กœ ์ •์  ํŒŒ์ผ ์„œ๋น™
  • ํฌํŠธ: Host 3000 โ†’ Container 80
  • ํ™˜๊ฒฝ๋ณ€์ˆ˜: REACT_APP_API_URL=http://localhost:8080 ๋“ฑ

Dockerfile (frontend/Dockerfile)
FROM node:18-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm install

COPY . .
RUN npm run build

FROM nginx:stable-alpine

COPY nginx.conf /etc/nginx/nginx.conf

COPY --from=builder /app/build /usr/share/nginx/html

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]


2. Spring Boot

  • ๋ฒ ์ด์Šค ์ด๋ฏธ์ง€: openjdk:17, gradle:8.5-jdk17-alpine
  • ์ปจํ…Œ์ด๋„ˆ ์ˆ˜: 8๊ฐœ (Prod์šฉ, Dev์šฉ 4๊ฐœ, AZ ๋‹น 2๊ฐœ)
  • ์—ญํ• : ์‚ฌ์šฉ์ž ์ธ์ฆ, ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋“ฑ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜ํ–‰
  • ํฌํŠธ: Host 8080 โ†’ Container 8080
  • ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์˜ˆ์‹œ: SPRING_PROFILES_ACTIVE=prod, DB_HOST=root ๋“ฑ

Dockerfile (backend/Dockerfile)

FROM gradle:8.5-jdk17-alpine AS build

WORKDIR /app

COPY build.gradle.kts settings.gradle.kts ./
COPY gradle ./gradle
RUN gradle build --no-daemon || return 0

COPY . .
RUN gradle clean build --no-daemon

FROM eclipse-temurin:17-jdk-alpine

WORKDIR /app
COPY --from=build /app/build/libs/*.jar app.jar

EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

3. FastAPI (AI ์„œ๋น„์Šค)

  • ๋ฒ ์ด์Šค ์ด๋ฏธ์ง€: python:3.13-slim
  • ์ปจํ…Œ์ด๋„ˆ ์ˆ˜: 4๊ฐœ (GCP Compute Engine๋‹น 2๊ฐœ์”ฉ)
  • ์—ญํ• : ๋ชจ๋ธ ์ถ”๋ก  ๋ฐ AI API ์ œ๊ณต
  • ํฌํŠธ: Host 8000 โ†’ Container 8000
  • ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์˜ˆ์‹œ: MODEL_PATH=/app/model, ENV=prod ๋“ฑ

Dockerfile (ai/Dockerfile)

FROM python:3.13-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000


CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

์ฐธ๊ณ ์ž๋ฃŒ

์•„ํ‚คํ…์ณ ๊ฐœ์„