본문 바로가기
Docker

Docker 9회차 : Docker Compose 입문 (멀티 컨테이너 표준 운영)

by 마틴블레이크 2026. 1. 1.
반응형

Docker 9회차 : Docker Compose 입문 (멀티 컨테이너 표준 운영)

현업에서 컨테이너 운영이 어려워지는 순간은 대개 “컨테이너가 여러 개로 늘어났을 때”입니다. 웹 서버, DB, 캐시, 워커 등 서비스가 쪼개지면 docker run 명령은 길어지고, 옵션은 사람마다 달라지며, 재시작/로그/재배포 절차가 팀마다 제각각이 됩니다. Docker Compose는 이런 문제를 하나의 파일(예: compose.yaml)로 정리해, 실행 명령을 표준화하고 서비스 묶음을 일관되게 관리하도록 돕습니다.

목차

핵심 개념: Compose가 해결하는 문제

  • 실행 명령 표준화: 긴 docker run 옵션을 파일로 고정하여, 누가 실행해도 같은 결과가 나오게 만듭니다.
  • 서비스 묶음 관리: 웹/DB처럼 함께 떠야 하는 컨테이너를 “하나의 애플리케이션 스택”으로 다룹니다.
  • 운영 루틴 단순화: up, down, logs, restart 같은 명령이 서비스 묶음 단위로 동작합니다.
  • 재현 가능한 환경: 로컬/CI/테스트 서버에서 동일한 compose.yaml로 같은 구성의 환경을 재현합니다.

핵심 키워드: services, ports, volumes, environment, depends_on

Compose 파일을 처음 보면 항목이 많아 보이지만, 초보자가 먼저 익힐 것은 아래 5가지입니다. 이 5가지만 이해해도 “웹+DB” 수준의 멀티 컨테이너를 표준 운영 형태로 묶을 수 있습니다.

의미 초보자가 자주 실수하는 포인트
services 컨테이너(프로세스) 묶음의 정의(웹, DB 등) 서비스 이름을 애매하게 짓거나(예: app1) 역할이 섞여 유지보수가 어려워집니다.
ports 호스트 포트 ↔ 컨테이너 포트 매핑 이미 사용 중인 포트(예: 8080)를 또 쓰면 충돌합니다.
volumes 데이터/설정 파일을 영속화하거나 공유 DB 데이터를 볼륨 없이 올리면 컨테이너 삭제 시 데이터가 날아갈 수 있습니다.
environment 환경변수로 설정(계정, DB명 등)을 주입 민감정보를 파일에 하드코딩하면 공유/커밋 시 유출 위험이 있습니다.
depends_on 서비스 시작 순서를 어느 정도 보조 depends_on만으로 “DB가 완전히 준비됨”을 보장하지는 않습니다(운영 팁에서 보완 방법 설명).

산출물: compose.yaml 1개 (Web + DB) 예제

아래는 Web + DB를 한 번에 올리는 최소 실습 구성입니다. Web은 DB에 접속할 수 있는 간단한 웹 UI(adminer), DB는 postgres를 사용합니다. 별도 소스 코드 없이도 “멀티 컨테이너 운영 흐름”을 충분히 연습할 수 있습니다.

# compose.yaml
services:
  db:
    image: postgres:16-alpine
    container_name: demo-db
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app1234
      POSTGRES_DB: appdb
      TZ: Asia/Seoul
    ports:
      - "5432:5432"
    volumes:
      - db_data:/var/lib/postgresql/data
    restart: unless-stopped

  web:
    image: adminer:4
    container_name: demo-web
    ports:
      - "8080:8080"
    environment:
      TZ: Asia/Seoul
    depends_on:
      - db
    restart: unless-stopped

volumes:
  db_data:

구성 해설(핵심만)

  • db 서비스는 PostgreSQL을 띄우고, volumes로 데이터 디렉터리를 영속화합니다.
  • web 서비스는 Adminer 웹 UI를 8080 포트로 공개합니다. 브라우저에서 DB 접속을 시험할 수 있습니다.
  • depends_on은 “web이 db보다 먼저 뜨지 않도록” 시작 순서를 보조합니다. 다만 DB 준비(초기화)가 늦으면 접속 실패가 날 수 있으니, 운영 섹션에서 보완 팁을 같이 다룹니다.

Adminer 접속 정보(실습용)

  • 브라우저: http://localhost:8080
  • 시스템: PostgreSQL
  • 서버(Host): db (Compose 네트워크 내부에서는 서비스명이 곧 호스트명입니다)
  • 사용자/비밀번호/DB: app / app1234 / appdb

운영 기본 흐름: 실행/재시작/로그/특정 서비스만 재배포

Compose의 진짜 장점은 “올리는 것”이 아니라, 운영 루틴이 팀 표준으로 고정된다는 점입니다. 아래는 초보자가 반드시 손에 익혀야 할 운영 명령들입니다. (참고: 최신 Docker에서는 docker compose가 기본이며, 구버전은 docker-compose 명령을 사용합니다.)

# 1) 실행(백그라운드)
docker compose up -d

# 2) 상태 확인
docker compose ps

# 3) 로그 확인(전체 / 특정 서비스)
docker compose logs --tail=200
docker compose logs -f web
docker compose logs -f db

# 4) 재시작(전체 / 특정 서비스)
docker compose restart
docker compose restart web

# 5) 특정 서비스만 재배포(예: web만 다시 올리기)
docker compose up -d --force-recreate web

# 6) 컨테이너 내부로 들어가기(문제 분석용)
docker compose exec db sh
docker compose exec web sh

# 7) 종료(컨테이너만 내림: 볼륨 데이터는 유지)
docker compose down
운영 목표 자주 쓰는 명령 실무 팁
전체 기동 docker compose up -d 한 번에 스택이 올라가므로, 문서/온보딩이 단순해집니다.
로그 추적 docker compose logs -f web 장애 시에는 “전체 로그→의심 서비스 로그” 순서로 좁히는 습관이 중요합니다.
서비스만 재기동 docker compose restart web 전체 재기동보다 영향 범위가 작아 운영 부담이 줄어듭니다.
특정 서비스만 재배포 docker compose up -d --force-recreate web 구성이 바뀌었거나, 컨테이너를 깨끗하게 다시 만들고 싶을 때 사용합니다.
종료(데이터 유지) docker compose down DB 볼륨이 유지되므로, 다음 기동 시 데이터가 남아 있습니다.

“왜 web에서 DB 호스트를 localhost로 쓰면 안 되나요?”

Compose로 띄운 컨테이너들은 기본적으로 같은 네트워크에 연결되고, 서비스 이름이 DNS 이름처럼 동작합니다. 즉, web 컨테이너 안에서 DB로 접속할 때는 localhost가 아니라 db를 써야 합니다. localhost는 “내 컨테이너 자기 자신”을 가리키기 때문입니다.

depends_on의 한계와 초보자용 안전장치

depends_on은 시작 순서를 보조하지만, DB가 “완전히 준비되어 접속 가능”한 상태까지 기다리지는 않을 수 있습니다. 실무에서는 아래 중 하나를 선택합니다.

  • 애플리케이션 레벨 재시도: DB 연결이 실패하면 몇 초 간격으로 재시도하도록 애플리케이션 설정을 둡니다(가장 권장되는 일반 해법).
  • healthcheck 도입: DB 서비스에 헬스체크를 붙이고, 준비 상태를 기준으로 의존 서비스를 조절합니다(구성과 이해도가 조금 더 필요).

초기화(Reset) 운영 가이드: “실행/종료/초기화”를 표준 문서로 남기기

Compose 운영에서 가장 자주 필요한 문서는 “어떻게 올리고, 어떻게 내리고, 언제 데이터를 지우는가”입니다. 아래는 팀에서 그대로 복사해 운영 가이드로 써도 되는 형태로 정리한 체크리스트입니다.

1) 실행(기동) 가이드

  • 프로젝트 루트에서 compose.yaml 파일이 있는지 확인합니다.
  • docker compose up -d로 전체 서비스를 기동합니다.
  • docker compose ps로 web/db가 Up 상태인지 확인합니다.
  • 브라우저에서 http://localhost:8080 접속 후, 서버에 db를 입력해 DB 연결을 확인합니다.

2) 종료(중지/내림) 가이드

  • 단순 중지: docker compose stop
    컨테이너는 남아 있고, 다시 start로 올릴 수 있습니다.
  • 스택 내림: docker compose down
    컨테이너/네트워크는 정리되지만, volumes는 기본적으로 유지됩니다(데이터 보존).

3) 초기화(Reset) 가이드

초기화는 2단계로 나누는 것이 안전합니다. “컨테이너만 정리”와 “데이터까지 삭제”는 영향도가 완전히 다릅니다.

초기화 수준 명령 무엇이 지워지나요?
컨테이너만 초기화 docker compose down 컨테이너/네트워크 정리, DB 데이터(볼륨)는 유지
데이터까지 완전 초기화 docker compose down -v 컨테이너/네트워크 + 볼륨까지 삭제(DB 데이터 사라짐)
# (권장) 데이터 유지 초기화
docker compose down

# (주의) 데이터까지 완전 초기화 - DB 볼륨 삭제
docker compose down -v

# 이미지 최신화 후 재기동(필요 시)
docker compose pull
docker compose up -d

추가로 생각해볼 점: 실무에서 자주 막히는 포인트

  • 환경변수 관리: 실무에서는 비밀번호를 파일에 직접 쓰기보다 .env 또는 CI 비밀변수로 주입하는 방식이 안전합니다.
  • 포트 충돌: 로컬에 이미 Postgres가 있으면 5432가 충돌합니다.
    이 경우 호스트 포트를 바꿔 "15432:5432"처럼 운영하는 방식이 흔합니다.
  • 볼륨 백업: DB 운영은 “삭제 전 백업”이 기본입니다. 초기화 전에 데이터 백업/덤프 루틴을 팀 규칙으로 정해두면 사고를 줄일 수 있습니다.
  • 로그 습관: 장애 대응은 docker compose logs -f부터 시작하는 것이 가장 빠릅니다. 문제가 web인지 db인지부터 분리해 보시는 것이 좋습니다.
  • 서비스 분리 기준: “함께 배포/스케일링/장애영향이 같은가?”를 기준으로 서비스를 나누면 Compose/운영 설계가 자연스럽습니다.

 

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

반응형