[TECH-QA] Docker-compose

Docker Compose๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ Docker ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํ•˜๋‚˜์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ฒ˜๋Ÿผ ์‰ฝ๊ฒŒ ์ •์˜ํ•˜๊ณ , ์‹คํ–‰ํ•˜๊ณ , ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.
ํ•œ ๋งˆ๋””๋กœ ์š”์•ฝํ•˜๋ฉด โ†’ โ€œ์—ฌ๋Ÿฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ yaml ํŒŒ์ผ ํ•œ ์žฅ์œผ๋กœ ๋ฌถ์–ด์„œ ํ•œ ๋ฒˆ์— ๋„์šฐ๊ณ  ๋‚ด๋ฆฌ๋Š” ํŽธ๋ฆฌํ•œ ๋ฐฉ๋ฒ•โ€

์™œ Docker Compose๋ฅผ ์“ฐ๋‚˜์š”? (์ฃผ์š” ์žฅ์ )

  • 3๊ฐœ ์ด์ƒ๋ถ€ํ„ฐ ๋งค์šฐ ํŽธํ•จ
  • yaml ํŒŒ์ผ์— ํ•œ ๋ฒˆ๋งŒ ์ž‘์„ฑ
  • ์ž๋™์œผ๋กœ ๊ฐ™์€ ๋„คํŠธ์›Œํฌ ์ƒ์„ฑ & ์„œ๋น„์Šค ์ด๋ฆ„์œผ๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • depends_on์œผ๋กœ ์ˆœ์„œ ๋ณด์žฅ
  • docker-compose.yml ํ•˜๋‚˜๋กœ ๋™์ผ ํ™˜๊ฒฝ ๋ณด์žฅ
  • docker compose down ํ•œ ๋ฐฉ์— ์ •๋ฆฌ

๊ธฐ๋ณธ ์‚ฌ์šฉ ํ๋ฆ„ (๊ฐ€์žฅ ํ”ํ•œ ํŒจํ„ด)

  • ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— docker-compose.yml ํŒŒ์ผ ๋งŒ๋“ค๊ธฐ
  • ์„œ๋น„์Šค๋“ค ์ •์˜ํ•˜๊ธฐ
  • ๋ช…๋ น์–ด๋กœ ์‹คํ–‰

๊ฐ€์žฅ ๋งŽ์ด ์“ฐ๋Š” ๋ช…๋ น์–ด Top 5

docker compose up -d          # ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์‹คํ–‰
docker compose down           # ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ + ๋„คํŠธ์›Œํฌ + ๋ณผ๋ฅจ(์กฐ๊ฑด) ์ •๋ฆฌ
docker compose logs -f        # ์‹ค์‹œ๊ฐ„ ๋กœ๊ทธ ๋ณด๊ธฐ
docker compose ps             # ํ˜„์žฌ ์ƒํƒœ ํ™•์ธ
docker compose exec ์›น bash   # ํŠน์ • ์ปจํ…Œ์ด๋„ˆ ์•ˆ์œผ๋กœ ๋“ค์–ด๊ฐ€๊ธฐ

๊ธฐ๋ณธ ์‚ฌ์šฉ ํ๋ฆ„ (๊ฐ€์žฅ ํ”ํ•œ ํŒจํ„ด)

# compose.yaml  (์ตœ์‹  ํ”„๋กœ์ ํŠธ๋“ค์€ compose.yaml ๋ผ๊ณ  ์“ฐ๋Š” ์ถ”์„ธ)
services:
  web:                          # ์„œ๋น„์Šค ์ด๋ฆ„ (๋‚ด๋ถ€ DNS๋กœ ์‚ฌ์šฉ๋จ)
    image: nginx:alpine
    ports:
      - "8080:80"              # ํ˜ธ์ŠคํŠธ:์ปจํ…Œ์ด๋„ˆ
    volumes:
      - ./html:/usr/share/nginx/html:ro
    depends_on:
      - api

  api:
    build: ./backend             # ํ˜„์žฌ ํด๋”์˜ Dockerfile๋กœ ๋นŒ๋“œ
    environment:
      - DB_HOST=db
      - DB_USER=app
    depends_on:
      db:
        condition: service_healthy   # ๊ฑด๊ฐ•ํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆผ (v2.20+)

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpw
      MYSQL_DATABASE: myapp
    volumes:
      - mysql-data:/var/lib/mysql
    healthcheck:                  # depends_on condition๊ณผ ํ•จ๊ป˜ ์ž์ฃผ ์‚ฌ์šฉ
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 5s
      timeout: 3s
      retries: 5

volumes:
  mysql-data:                   # ๋ช…๋ช…๋œ ๋ณผ๋ฅจ (docker volume ls๋กœ ํ™•์ธ ๊ฐ€๋Šฅ)


 postgres:
    image: docker.io/library/postgres:15-alpine
    container_name: postgres
    restart: always
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: postgres
    ports:
      - "25432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: docker.io/library/redis:7-alpine
    container_name: redis
    restart: always
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

์ž์ฃผ ์“ฐ์ด๋Š” ์ฃผ์š” ํ‚ค์›Œ๋“œ ํ•œ๋ˆˆ์— ์ •๋ฆฌ

ํ‚ค
์˜๋ฏธ
์˜ˆ์‹œ
image์‚ฌ์šฉํ•  ์ด๋ฏธ์ง€nginx:latest
build์ง์ ‘ ๋นŒ๋“œํ•  ๊ฒฝ๋กœ. ๋˜๋Š” ./frontend
portsํฌํŠธ ๋งคํ•‘"3000:3000"
key0.75rem12px
volumes๋ฐ์ดํ„ฐ/์ฝ”๋“œ ๋งˆ์šดํŠธ./app:/app
environmentํ™˜๊ฒฝ๋ณ€์ˆ˜- DEBUG=true - API_PORT=${API_PORT} - POSTGRESQL_USERNAME=${POSTGRESQL_USERNAME} - POSTGRESQL_PASSWORD=${POSTGRESQL_PASSWORD} - POSTGRESQL_DB=${POSTGRESQL_DB}
env_file.env ํŒŒ์ผ ์ฝ๊ธฐ.env
depends_ondepends_on- db
networks์ปค์Šคํ…€ ๋„คํŠธ์›Œํฌ ์‚ฌ์šฉbackend-net
restart์ž๋™ ์žฌ์‹œ์ž‘ ์ •์ฑ…unless-stopped
healthcheck์ปจํ…Œ์ด๋„ˆ ๊ฑด๊ฐ• ์ฒดํฌCMD curl -f http://localhost

docker compose ์žฌ์‹คํ–‰

up
docker-compose --env-file .env.local -f docker-compose.yml up

down
docker-compose --env-file .env.local -f docker-compose.yml down

volume (db ํฌํ•จ) ๋„ ๋‹ค ์ œ๊ฑฐ
docker-compose --env-file .env.local -f docker-compose.yml down -v