docker run 명령어를 일일이 입력하며 컨테이너를 개별적으로 실행하고 네트워크를 연결하는 과정은 번거롭고 실수할 가능성이 큽니다. 이러한 불편함을 해결해 주는 도구가 바로 Docker Compose입니다.이번 글에서는 Docker Compose를 사용해 로컬 환경에서 여러 컨테이너를 효율적으로 관리하고 연결하는 기본적인 방법에 대해 상세히 알아보겠습니다.
01. 핵심 기준 한눈에 보기
✓ 여러 컨테이너를 단 하나의 설정 파일로 통합 관리하는 핵심 구조를 파악해 봅니다.Docker Compose는
docker-compose.yml이라는 YAML 형식의 설정 파일 하나로 여러 컨테이너의 실행 옵션, 네트워크, 볼륨 등을 정의합니다. 복잡한 명령어를 매번 입력할 필요 없이 간단한 명령 하나만으로 전체 시스템을 시작하거나 종료할 수 있습니다.| 구분 | 개별 Docker 실행 (docker run) | Docker Compose 실행 (docker-compose) |
| 설정 방식 | 터미널 명령어에 모든 옵션 직접 입력 | docker-compose.yml 파일에 명세 작성 |
| 관리 대상 | 단일 컨테이너 단위 | 여러 개의 컨테이너 그룹 단위 |
| 네트워크 연결 | 사용자 정의 네트워크 생성 후 일일이 지정 | 기본적으로 동일한 브리지 네트워크 자동 생성 |
| 재현성 | 명령 기록이 없으면 설정 재현이 어려움 | 파일만 공유하면 어디서든 동일하게 실행 가능 |
02. docker-compose.yml 기본 구조 작성하기
✓ 웹 서버와 데이터베이스 컨테이너를 함께 정의하는 기본 구문을 살펴봅니다.Docker Compose 파일은 보통 project 루트 디렉토리에 위치시킵니다. 다음은 Nginx 웹 서버와 PostgreSQL 데이터베이스 두 개의 컨테이너를 동시에 정의하는 기본적인 작성 예시입니다.
YAML
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
POSTGRES_DB: mydatabase
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
✓ 주요 키워드 설명
services: 실행할 컨테이너들을 정의하는 최상위 항목입니다. 각 하위 항목이 하나의 컨테이너가 됩니다.image: 사용할 Docker 이미지를 지정합니다. 로컬에 없는 경우 Docker Hub에서 자동으로 다운로드합니다.ports: 호스트와 컨테이너 간의 포트 바인딩을 설정합니다.호스트포트:컨테이너포트형태로 작성합니다.depends_on: 컨테이너 간의 실행 순서를 지정합니다. 위 설정에서는db컨테이너가 먼저 실행된 후web컨테이너가 실행됩니다.environment: 컨테이너 내부에서 사용할 환경변수를 설정합니다.volumes: 데이터를 컨테이너가 종료되어도 유지할 수 있도록 호스트의 디렉토리나 Docker 볼륨에 매핑합니다.
03. 컨테이너 간 내부 네트워크 연결 원리
✓ 서비스 이름을 통한 자동 DNS 확인 과정을 이해해 봅니다.Docker Compose로 여러 컨테이너를 함께 실행하면 Compose는 자동으로 전용 브리지 네트워크를 생성하고 정의된 모든 컨테이너를 해당 네트워크에 참여시킵니다.
따라서 컨테이너끼리 통신할 때 IP 주소를 직접 입력할 필요가 없습니다.
services 아래에 지정한 서비스 이름(Service Name)이 곧 도메인 이름(DNS)으로 기능하기 때문입니다.예를 들어, 웹 애플리케이션 서비스에서 데이터베이스에 접속할 때 호스트 이름으로
localhost나 IP가 아닌 db라는 서비스 이름을 입력하기만 하면 Docker 내부 DNS가 이를 올바른 컨테이너 IP로 변환해 줍니다. 이를 통해 다른 컨테이너와의 연결 설정을 매우 손쉽게 처리할 수 있습니다.04. 자주 사용하는 Docker Compose 주요 명령어
✓ 로컬 환경에서 컨테이너를 생성, 실행, 종료하는 필수 명령어를 알아봅니다.작성한
docker-compose.yml 파일을 기반으로 서비스를 운용할 때 자주 사용하는 대표적인 명령어 목록입니다.- 컨테이너 백그라운드 실행Bash
docker-compose up -dup명령어는 필요한 이미지를 다운로드하고 네트워크 및 볼륨을 생성한 뒤 컨테이너를 실행합니다.-d옵션을 붙이면 데몬 형태(백그라운드)로 실행됩니다. - 실행 중인 서비스 상태 확인Bash
docker-compose ps - 로그 확인하기Bash
docker-compose logs -f-f옵션을 사용하면 실시간으로 출력되는 컨테이너 로그를 추적할 수 있습니다. - 컨테이너 정지 및 삭제실행 중인 컨테이너와 네트워크를 일괄 정지하고 삭제합니다. 볼륨까지 함께 삭제하고 싶다면Bash
docker-compose downdocker-compose down -v명령어를 사용합니다.
05. 효율적인 로컬 관리를 위한 실무 팁
✓ 유지보수성을 높이고 보안을 강화하는 운용 전략을 확인해 봅니다.- 환경변수 파일(.env) 분리비밀번호나 API 키 같은 민감한 정보는
docker-compose.yml에 직접 작성하지 않고.env파일로 분리하여 관리하는 것이 안전합니다. Compose는 실행 시 동일 경로의.env파일을 자동으로 읽어옵니다. - 소구조 분리와 재사용성개발 환경과 운영 환경의 설정이 다를 경우
docker-compose.override.yml파일을 활용해 개발용 설정을 덮어쓰는 방식을 권장합니다. - 리소스 제한 설정로컬 개발PC의 자원이 부족해지지 않도록 각 컨테이너의 CPU 및 메모리 사용량을 적절히 제한해 두면 안정적인 개발 환경을 유지할 수 있습니다.
자주 묻는 질문 (FAQ)
Q1. docker-compose up 실행 시 특정 컨테이너만 빌드하거나 다시 실행할 수 있나요?
네, 가능합니다. 전체 서비스를 다시 시작하지 않고 특정 서비스만 지정하여 재실행할 수 있습니다. 예를 들어web 서비스만 다시 빌드하고 실행하려면 docker-compose up -d --build web 명령어를 입력하시면 됩니다.Q2. depends_on을 설정했는데 데이터베이스 준비가 안 된 상태에서 웹 앱이 켜져 에러가 납니다.
depends_on은 컨테이너의 '실행 시작' 순서만 보장할 뿐, 내부 애플리케이션이 완전히 준비될 때까지 기다려주지는 않습니다. 이를 해결하기 위해서는 애플리케이션 코드에 재시도 로직을 구현하거나, wait-for-it.sh 같은 헬스체크 스크립트를 컨테이너 시작 명령에 적용해 주셔야 합니다.Q3. 기존에 따로 만들어둔 외부 Docker 네트워크와 연결할 수도 있나요?
네, 가능합니다.docker-compose.yml 파일 하단에 networks 항목을 정의하고 external: true 옵션을 주어 이미 존재하는 외부 네트워크에 컨테이너들을 참가시킬 수 있습니다.