Docker Compose 다중 컨테이너 운영 완벽 가이드 2026: VPS에서 웹+DB+캐시까지

이 글에는 제휴 링크(affiliate link)가 포함되어 있습니다. Vultr·DigitalOcean 가입 링크로 가입하시면 추가 비용 없이 크레딧 혜택을 받으실 수 있으며, 블로그 운영에 도움이 됩니다.

Docker Compose를 사용하면 여러 컨테이너를 하나의 파일로 정의하고 관리할 수 있어 운영이 매우 편리해집니다.

웹, DB, 캐시 등 다중 컨테이너 환경을 즉시 배포하고 관리하는 예시 설정을 제공합니다.

Docker Compose로 다중 컨테이너를 한 번에 관리하려면 어떻게 해야 할까요?

VPS 하나에 서비스를 여러 개 올리면 금방 컨테이너가 늘어납니다. 웹 서버, 데이터베이스, 캐시, 리버스 프록시… docker run 명령어로 일일이 띄우면 관리가 불가능해집니다. Docker Compose는 docker-compose.yml 파일 하나로 여러 컨테이너를 정의하고 up 한 번에 전부 실행할 수 있게 해줍니다.

Docker Compose 다중 컨테이너 운영 완벽 가이드 2026: VPS에서 웹+DB+캐시까지
사진: wirralwater / flickr (BY)

이 튜토리얼에서는 웹 앱 + PostgreSQL + Redis로 구성된 다중 컨테이너 서비스를 Docker Compose로 구성하는 전체 과정을 다룹니다. Vultr, DigitalOcean, Hetzner VPS에서 그대로 적용할 수 있습니다.

1. Docker Compose 설치

Docker가 이미 설치되어 있다면 Compose plugin으로 충분합니다:

# Docker 공식 apt 저장소를 등록한 뒤(공식 문서 참고) 설치
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

저장소 등록 절차는 Docker 공식 설치 문서를 따르세요.

버전 확인:

docker compose version

2. docker-compose.yml 작성

세 개의 서비스(web, db, cache)를 정의합니다:

services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://app:${DB_PASSWORD}@db:5432/app
      - REDIS_URL=redis://cache:6379
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: app
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  cache:
    image: redis:7-alpine
    volumes:
      - redisdata:/data
    restart: unless-stopped

volumes:
  pgdata:
  redisdata:
3. 환경변수 .env 관리 — 요약

3. 환경변수 .env 관리

비밀번호 등 민감 정보는 .env 파일로 분리합니다. 절대 git에 커밋하지 마세요.

# .env
DB_PASSWORD=매우강력한비밀번호

.gitignore에 추가:

echo ".env" >> .gitignore

4. 전체 서비스 실행

docker compose up -d

컨테이너 상태 확인:

docker compose ps
docker compose logs -f web

5. 데이터 영속화 — named volumes

컨테이너를 지워도 데이터는 남아야 합니다. volumes 섹션으로 named volume을 정의하면, docker compose down을 해도 DB 데이터가 보존됩니다. 완전히 삭제하려면 -v 옵션을 줍니다:

docker compose down -v   # volume까지 삭제 — 주의!
6. 컨테이너 간 통신 — networks — 요약

6. 컨테이너 간 통신 — networks

Docker Compose는 같은 docker-compose.yml에 정의된 서비스끼리 자동으로 네트워크를 구성합니다. db, cache 같은 서비스 이름으로 통신할 수 있습니다. 별도 network를 정의하면 더 세밀하게 제어할 수 있습니다.

7. 운영 패턴 — 헬스체크와 재시작 정책은 어떻게 설정할까요?

healthcheck로 컨테이너가 정상인지 주기적으로 검사합니다. DB가 준비된 뒤에 웹 서버가 실행되도록 depends_on: condition: service_healthy를 사용합니다. restart: unless-stopped로 서버 재부팅 시 자동 복구되게 합니다.

마무리: docker compose up 한 줄의 힘

Docker Compose를 쓰면 인프라가 코드로 관리됩니다. docker-compose.yml 하나로 개발·운영 환경을 동일하게 재현할 수 있고, 새 VPS로 이전할 때도 compose 파일을 옮기고 데이터 볼륨을 복원하면 같은 환경을 다시 만들 수 있습니다.

추천 VPS: 이 튜토리얼은 Vultr, DigitalOcean, Hetzner VPS에서 그대로 적용됩니다.

자주 묻는 질문 (FAQ)

Q1. docker run으로 하나씩 띄우는 것과 뭐가 다른가요?

docker-compose.yml 파일 하나에 웹·DB·캐시를 모두 정의해 두고 docker compose up -d 한 번으로 전부 실행할 수 있습니다. 컨테이너가 늘어날수록 docker run 방식은 관리가 사실상 불가능해집니다.

Q2. 컨테이너를 지우면 DB 데이터도 사라지나요?

volumes 섹션에 named volume(예: pgdata)을 정의해 두면 docker compose down을 해도 데이터가 남습니다. 다만 docker compose down -v는 volume까지 삭제하므로 주의해야 합니다.

Q3. 웹 서버가 DB보다 먼저 떠서 연결이 실패합니다.

db 서비스에 healthcheck(pg_isready -U app)를 정의하고 web 쪽에 depends_on: db: condition: service_healthy를 걸면, DB가 정상 응답한 뒤에 웹 서버가 시작됩니다.

Q4. DB 비밀번호는 어디에 두나요?

docker-compose.yml에 직접 쓰지 말고 .env 파일로 분리해 ${DB_PASSWORD} 형태로 참조하세요. .env는 반드시 .gitignore에 추가해 git에 커밋되지 않게 해야 합니다.

관련 글