Docker Compose

๋„์ปค ์ปดํฌ์ฆˆ๋Š” ๊ฐœ๋ณ„ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ผ์ผ์ด ์ œ์–ดํ•˜๋Š” ๋Œ€์‹  ํ•˜๋‚˜์˜ ์„ค์ • ํŒŒ์ผ์„ ํ†ตํ•ด ์ „์ฒด ์‹œ์Šคํ…œ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ํ†ตํ•ฉ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.

  • ๋ณต์žกํ•œ ์„œ๋น„์Šค ํ™˜๊ฒฝ์„ ์ฝ”๋“œ๋กœ ๊ด€๋ฆฌ(IaC)ํ•˜๊ธฐ ์œ„ํ•ด docker-compose.yml ํŒŒ์ผ์„ ์‚ฌ์šฉ

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ตฌ์„ฑ ์š”์†Œ์ธ ์„œ๋น„์Šค, ๋„คํŠธ์›Œํฌ, ๋ณผ๋ฅจ ๋“ฑ์„ ์„ ์–ธ์ ์œผ๋กœ ์ •์˜ํ•˜์—ฌ ์‹คํ–‰ ํ™˜๊ฒฝ์˜ ์ผ๊ด€์„ฑ ์œ ์ง€

  • ๋‹จ์ผ ๋ช…๋ น์–ด๋กœ ์—ฌ๋Ÿฌ ์ปจํ…Œ์ด๋„ˆ์˜ ์ƒ์„ฑ, ์‹คํ–‰, ์ค‘์ง€, ์‚ญ์ œ๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ ๊ฐœ๋ฐœ ๋ฐ ์šด์˜ ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ

docker-compose.yml ๊ธฐ๋ณธ ๊ตฌ์กฐ

์„ค์ • ํŒŒ์ผ์€ ํฌ๊ฒŒ ์„œ๋น„์Šค, ๋„คํŠธ์›Œํฌ, ๋ณผ๋ฅจ ์„น์…˜์œผ๋กœ ๊ตฌ๋ถ„๋˜์–ด ์ „์ฒด ์‹œ์Šคํ…œ์˜ ์•„ํ‚คํ…์ฒ˜๋ฅผ ๋ช…์‹œํ•œ๋‹ค.

  • services: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ฐ๊ฐ์˜ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ •์˜ํ•˜๋ฉฐ ๊ฐ€์žฅ ํ•ต์‹ฌ์ ์ธ ์—ญํ• ์„ ์ˆ˜ํ–‰

  • networks: ์„œ๋น„์Šค ๊ฐ„ ํ†ต์‹ ์„ ์œ„ํ•œ ๊ฐ€์ƒ ๋„คํŠธ์›Œํฌ๋ฅผ ์„ค์ •ํ•˜๋ฉฐ ์™ธ๋ถ€ ์ ‘๊ทผ ์ฐจ๋‹จ ๋“ฑ ๋ณด์•ˆ ์ •์ฑ… ์ ์šฉ ๊ฐ€๋Šฅ

  • volumes: ๋ฐ์ดํ„ฐ ์˜์†ํ™”๋ฅผ ์œ„ํ•œ ์Šคํ† ๋ฆฌ์ง€ ์„ค์ •์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ ์‚ญ์ œ ํ›„์—๋„ ๋ฐ์ดํ„ฐ ๋ณด์กด ๊ฐ€๋Šฅ

์‹ค๋ฌดํ˜• ์„œ๋น„์Šค ๊ตฌ์„ฑ ์˜ˆ์‹œ (Spring Boot, MySQL, Redis)

services:
  # MySQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋น„์Šค
  database:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: myapp
      MYSQL_USER: myuser
      MYSQL_PASSWORD: mypassword
      MYSQL_ROOT_PASSWORD: rootpassword
    volumes:
      - db_data:/var/lib/mysql
    networks:
      # ๋‚ด๋ถ€ ์„œ๋น„์Šค์šฉ ๋„คํŠธ์›Œํฌ๋งŒ ํ• ๋‹นํ•˜์—ฌ ์™ธ๋ถ€ ์ ‘๊ทผ ์ฐจ๋‹จ
      - backend_net
    healthcheck:
      # mysqladmin ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DB ์„œ๋ฒ„๊ฐ€ ์‘๋‹ต ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์ธ์ง€ ์ฃผ๊ธฐ์ ์œผ๋กœ ์ ๊ฒ€
      test: [ "CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "myuser", "-pmypassword" ]
      interval: 10s
      timeout: 5s
      retries: 5

  # Redis ์บ์‹œ ์„œ๋น„์Šค
  redis:
    image: redis:7-alpine
    networks:
      - backend_net

  # ์Šคํ”„๋ง ๋ถ€ํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋น„์Šค
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      # ์™ธ๋ถ€ ๋ธŒ๋ผ์šฐ์ €๋‚˜ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ ‘๊ทผํ•  ํฌํŠธ ๋งคํ•‘
      - "8080:8080"
    environment:
      # ์ปจํ…Œ์ด๋„ˆ ์„œ๋น„์Šค ์ด๋ฆ„์„ ํ˜ธ์ŠคํŠธ ์ฃผ์†Œ๋กœ ์‚ฌ์šฉ
      SPRING_DATASOURCE_URL: jdbc:mysql://database:3306/myapp?allowPublicKeyRetrieval=true&useSSL=false
      SPRING_DATASOURCE_USERNAME: myuser
      SPRING_DATASOURCE_PASSWORD: mypassword
      SPRING_REDIS_HOST: redis
    depends_on:
      # ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๋‹จ์ˆœ ์‹œ์ž‘์ด ์•„๋‹Œ ํ—ฌ์Šค์ฒดํฌ ๊ฒฐ๊ณผ 'healthy' ์ƒํƒœ์ผ ๋•Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘
      database:
        condition: service_healthy
    networks:
      # ์™ธ๋ถ€ ํ†ต์‹ (frontend)๊ณผ ๋‚ด๋ถ€ ํ†ต์‹ (backend)์„ ๋ชจ๋‘ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๋‘ ๋„คํŠธ์›Œํฌ์— ์—ฐ๊ฒฐ
      - frontend_net
      - backend_net

# ๋„คํŠธ์›Œํฌ ์ •์˜ ์„น์…˜
networks:
  # ์™ธ๋ถ€์™€ ์—ฐ๊ฒฐ๋˜๋Š” ๋„คํŠธ์›Œํฌ
  frontend_net:
    driver: bridge
  # ๋‚ด๋ถ€ ์„œ๋น„์Šค ์ „์šฉ ๋„คํŠธ์›Œํฌ
  backend_net:
    driver: bridge
    # internal ์˜ต์…˜์„ ํ†ตํ•ด ์ด ๋„คํŠธ์›Œํฌ์— ์—ฐ๊ฒฐ๋œ ์ปจํ…Œ์ด๋„ˆ๋“ค์˜ ์™ธ๋ถ€ ์ธํ„ฐ๋„ท ํ†ต์‹  ์ œํ•œ
    internal: true

# ๋ณผ๋ฅจ ์ •์˜ ์„น์…˜
volumes:
  db_data:

์„œ๋น„์Šค ์ƒ์„ธ ์„ค์ •

๊ฐ ์„œ๋น„์Šค ์„น์…˜์—์„œ๋Š” ์ปจํ…Œ์ด๋„ˆ์˜ ์„ธ๋ถ€ ์ŠคํŽ™๊ณผ ๋™์ž‘ ๋ฐฉ์‹์„ ์ •์˜ํ•œ๋‹ค.

  • image vs build: ์ด๋ฏธ ๊ตฌ์ถ•๋œ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ฌ์ง€ ํ˜น์€ ํŠน์ • ๊ฒฝ๋กœ์˜ Dockerfile์„ ์ฝ์–ด ์ง์ ‘ ๋นŒ๋“œํ• ์ง€ ๊ฒฐ์ •

  • ports: ํ˜ธ์ŠคํŠธ ๋จธ์‹ ์˜ ํฌํŠธ์™€ ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ ํฌํŠธ๋ฅผ ์—ฐ๊ฒฐํ•˜์—ฌ ์™ธ๋ถ€ ์ ‘๊ทผ ํ—ˆ์šฉ

  • depends_on: ์„œ๋น„์Šค ๊ฐ„์˜ ์‹œ์ž‘ ์ˆœ์„œ๋ฅผ ์ •์˜ํ•˜์ง€๋งŒ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์™„์ „ํ•œ ์ค€๋น„ ์ƒํƒœ๊นŒ์ง€ ๋ณด์žฅํ•˜์ง€๋Š” ์•Š์Œ

    • ํ”„๋กœ์„ธ์Šค ์‹œ์ž‘๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‚ด๋ถ€ ๋กœ์ง ๊ฐ€๋™ ์—ฌ๋ถ€๊นŒ์ง€ ํ™•์ธํ•˜๋ ค๋ฉด healthcheck์™€ ์—ฐ๋™ ํ•„์ˆ˜

  • environment: DB ์ ‘์† ์ •๋ณด๋‚˜ API ํ‚ค์™€ ๊ฐ™์€ ๋™์ ์ธ ์„ค์ •๊ฐ’์„ ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€๋กœ ์ฃผ์ž…

๋„คํŠธ์›Œํฌ ๊ฒฉ๋ฆฌ ๋ฐ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ

๋ณด์•ˆ ๊ฐ•ํ™”๋ฅผ ์œ„ํ•ด ์„œ๋น„์Šค๋ณ„ ์ ‘๊ทผ ๋ฒ”์œ„๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ  ์ค‘์š” ๋ฐ์ดํ„ฐ์˜ ์˜์†์„ฑ์„ ํ™•๋ณดํ•ด์•ผ ํ•œ๋‹ค.

spinner
  • ๋„คํŠธ์›Œํฌ ๋ถ„๋ฆฌ: ์™ธ๋ถ€ ์ธํ„ฐ๋„ท๊ณผ ์—ฐ๊ฒฐ๋˜๋Š” frontend_net๊ณผ ๋‚ด๋ถ€ ํ†ต์‹ ์šฉ backend_net์„ ๊ตฌ๋ถ„ํ•˜์—ฌ ์„ค๊ณ„

  • internal ์˜ต์…˜: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์บ์‹œ ์„œ๋ฒ„๋ฅผ ๋‚ด๋ถ€ ์ „์šฉ ๋„คํŠธ์›Œํฌ์— ๋ฐฐ์น˜ํ•˜์—ฌ ํ˜ธ์ŠคํŠธ ์™ธ๋ถ€์—์„œ์˜ ์ง์ ‘ ์ ‘๊ทผ์„ ์›์ฒœ ์ฐจ๋‹จ

  • ๋ช…๋ช…๋œ ๋ณผ๋ฅจ(Named Volume): ๋„์ปค๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ๋ณผ๋ฅจ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ŠคํŠธ ๊ฒฝ๋กœ ์˜์กด์„ฑ์„ ๋‚ฎ์ถ”๊ณ  ๋ฐ์ดํ„ฐ ์ด์‹์„ฑ ํ™•๋ณด

๋„คํŠธ์›Œํฌ ์„ค๊ณ„์˜ ํ•ต์‹ฌ ์›๋ฆฌ

์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์™ธ๋ถ€ ๋ง์œผ๋กœ๋ถ€ํ„ฐ ํ•ต์‹ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋…ผ๋ฆฌ์ ์œผ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

  • ๊ณ„์ธตํ˜• ๋„คํŠธ์›Œํฌ: ์‚ฌ์šฉ์ž ์š”์ฒญ์„ ๋ฐ›๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณ„์ธต๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ธํ”„๋ผ ๊ณ„์ธต์„ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๊ฒฉ๋ฆฌ

  • ์ ‘๊ทผ ์ œ์–ด: ์™ธ๋ถ€ ์‚ฌ์šฉ์ž๋Š” ์˜ค์ง ํ•œ์ •๋œ ์ง„์ž…๋กœ๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์‹œ์Šคํ…œ์— ์ง„์ž… ๊ฐ€๋Šฅ

  • ์ง์ ‘ ์—ฐ๊ฒฐ ์ฐจ๋‹จ: DB -.-x User์™€ ๊ฐ™์ด ์™ธ๋ถ€์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋‚˜ ์บ์‹œ๋กœ ์ง์ ‘ ์ ‘๊ทผํ•˜๋Š” ๊ฒฝ๋กœ๋Š” ์ฐจ๋‹จํ•˜๋Š” ๊ฒƒ์ด ๋ณด์•ˆ์ƒ์œผ๋กœ ๊ถŒ์žฅ

๋ฐ์ดํ„ฐ ์˜์†ํ™” ์ „๋žต

์ปจํ…Œ์ด๋„ˆ์˜ ๋น„์˜์†์  ํŠน์„ฑ์„ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด ๋ณผ๋ฅจ ๊ธฐ์ˆ ์„ ์ ์ ˆํžˆ ๋ฐฐ๋ถ„ํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐ์ดํ„ฐ: MySQL์˜ ๋ฐ์ดํ„ฐ ํด๋”(/var/lib/mysql)๋Š” ๋ฐ˜๋“œ์‹œ ๋ช…๋ช…๋œ ๋ณผ๋ฅจ์— ๋งˆ์šดํŠธํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ ์‚ญ์ œ ์‹œ์—๋„ ๋ณดํ˜ธ

  • ์„ค์ • ํŒŒ์ผ: ์ˆ˜์ •์ด ์žฆ์€ ํ™˜๊ฒฝ ์„ค์ • ํŒŒ์ผ์€ ๋ฐ”์ธ๋“œ ๋งˆ์šดํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ŠคํŠธ์—์„œ ์ง์ ‘ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์ด ํšจ์œจ์ 

  • ๋กœ๊ทธ ๋ฐ์ดํ„ฐ: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๊ทธ๋Š” ๋ณผ๋ฅจ์— ์ €์žฅํ•˜๊ฑฐ๋‚˜, ๋ณ„๋„์˜ ๋กœ๊ทธ ๋“œ๋ผ์ด๋ฒ„๋ฅผ ํ†ตํ•ด ์™ธ๋ถ€ ๋กœ๊ทธ ์ˆ˜์ง‘ ์‹œ์Šคํ…œ์œผ๋กœ ์ „์†ก

Last updated