
멀티 컨테이너 환경을 한 번에 올리고 내릴 때 사용하는 게 Docker Compose다.
여기서는 개념 → docker-compose.yml 구조 → 자주 쓰는 명령 → 네트워크까지 정리한다.
실제 서비스는 보통
컨테이너 기준으로 보면 여러 개의 컨테이너를 한 번에 관리해야 하는 상황이 많다.
Docker Compose는 이런 멀티 컨테이너를
docker-compose.yml 하나로 정의하고, 명령 몇 개로 통째로 관리하는 도구다.
설정 파일 포맷은 YAML을 사용한다.
YAML 특징만 딱 잡고 가면 된다.
# 사용.예시:
person:
name: catohgiraffer
age: 24
address: Korea
phone: "01052520124"
email: catohgiraffer@mail.com
Compose 파일(docker-compose.yml)도 이 YAML 문법 그대로 따라간다.
docker-compose.yml 구조와 주요 키워드예시:
version: "3"
services:
app:
build:
context: ./DOCKER_EXAMPLE
dockerfile: Dockerfile
ports:
- "8080:8080"
container_name: web
restart: always
depends_on:
- db
db:
image: mysql:5.7
volumes:
- ./mysqldata:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=catohgiraffers
- MYSQL_DATABASE=cat0124!!
ports:
- "3306:3306"
container_name: db
각 항목별 의미를 나눠보면:
versionversion: "3"
servicesservices:
app:
...
db:
...
app, db 같은 것이 “서비스 이름”imageservices:
app:
image: catohgiraffers:1.0
db:
image: mysql:5.7
docker run mysql:5.7 할 때의 이미지 지정과 같다.FROM 과 개념은 비슷하지만, Compose는 “어떤 이미지 쓸지”만 적는 쪽에 가깝다.buildservices:
app:
build:
context: .
dockerfile: Dockerfile
context: 빌드 컨텍스트 경로 (보통 프로젝트 루트)dockerfile: 사용할 Dockerfile 이름/경로image 대신 build 를 쓰면 docker-compose up 시 자동으로 이미지 빌드 후 컨테이너 생성.commandservices:
app:
build:
context: .
dockerfile: Dockerfile
command: java -jar app.jar
CMD 를 덮어쓰는 느낌으로 이해하면 된다.portsservices:
app:
ports:
- "8080:8080"
docker run -p 8080:8080 과 동일한 포트 포워딩 설정."호스트포트:컨테이너포트" 형식의 문자열 리스트로 작성.depends_onservices:
app:
depends_on:
- db
db:
...
db 가 먼저 올라가고 그 다음에 app 이 올라간다.environmentservices:
app:
environment:
- POSTGRES_HOST=db
- POSTGRES_USER=catohgiraffers
- POSTGRES_PASSWORD=cat0124!!
- POSTGRES_DB=ohgiraffers
docker run -e KEY=VALUE 와 같은 역할.volumesservices:
app:
volumes:
- nc_data:/var/web/
db:
volumes:
- db_data:/var/lib/mysql/data
컨테이너 데이터가 사라지지 않도록 호스트 또는 볼륨을 마운트하는 기능.
형식은 대략
{호스트경로}:{컨테이너경로}{볼륨명}:{컨테이너경로}restartservices:
app:
restart: always
컨테이너 재시작 정책.
예:
no (기본값)on-failurealwaysunless-stoppedCompose는 docker 와 헷갈리지 않게 주의.
기본적으로 docker-compose.yml 이 있는 디렉터리에서 실행한다.
up)docker-compose up
docker-compose up -d
-d: 백그라운드로 실행(detach).자주 쓰는 옵션:
| 옵션 | 설명 |
|---|---|
-d | 백그라운드 실행 |
--build | up 전에 이미지를 먼저 빌드 |
--no-build | 이미지가 없어도 빌드하지 않음 |
--abort-on-container-exit | 하나라도 종료되면 전체 종료 (테스트용으로 유용) |
ps, ls)docker-compose ps
docker-compose ls
주요 옵션:
| 옵션 | 설명 |
|---|---|
-q | 컨테이너 ID만 출력 |
--services | 서비스 이름만 출력 |
-a / --all | 종료된 컨테이너까지 포함 |
run)docker-compose run {서비스명} {명령}
# 예시
docker-compose run web env
docker run 과 비슷하지만 Compose 설정을 그대로 활용.옵션:
| 옵션 | 설명 |
|---|---|
-d | 백그라운드 실행 |
--name | 컨테이너 이름 지정 |
--rm | 명령 실행 후 컨테이너 자동 삭제 |
start, stop)docker-compose start {서비스명}
docker-compose stop {서비스명}
logs)docker-compose logs {서비스명}
docker-compose logs -f {서비스명}
-f 로 tail 모드처럼 실시간 모니터링 가능.config)docker-compose config
down)docker-compose down
up 으로 만든 컨테이너, 네트워크 등을 한 번에 종료 + 제거.-v 옵션을 추가하면 해당 Compose가 만든 볼륨까지 삭제된다.Compose를 쓰면 네트워크도 자동으로 많이 처리된다.
그래도 구조를 알고 있으면 에러가 났을 때 훨씬 편하다.
각 컨테이너는 네트워크 샌드박스라 부르는 독립된 네임스페이스 안에서 실행된다.
샌드박스 안에는 네트워크 엔드포인트(Endpoint)가 있고,
여러 엔드포인트가 모여 가상 네트워크(Network) 를 이룬다.
Docker Engine은 네트워크 드라이버, IPAM 드라이버를 통해
bridge
host
overlay
macvlan
none
프로젝트명_default 네트워크가 자동으로 생성된다.http://db:3306
http://app:8080
(서비스 이름이 곧 DNS 이름처럼 동작)
원하면 docker-compose.yml 에 직접 네트워크를 정의할 수도 있다.
networks:
app-net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
그리고 서비스 쪽에:
services:
app:
networks:
- app-net
db:
networks:
- app-net
이런 식으로 묶어주면 선택된 서비스끼리만 같은 네트워크에 속하게 할 수 있다.
docker network ls # 네트워크 목록
docker network inspect 이름 # 상세 정보
docker network create --driver bridge app-net
docker network rm 이름
같은 네트워크에 속한 컨테이너끼리만 서로 통신 가능.
하나의 컨테이너를 여러 네트워크에 붙여서 내부망/외부망 분리도 가능.
Compose 환경에서는 보통
서비스 이름을 기준으로 DNS가 자동 설정되고이 정도만 이해하고 있으면:
docker build 로 이미지 만들고docker-compose.yml 로 여러 컨테이너를 한 번에 구성docker-compose up/down 으로 로컬 개발 환경 전체를 스위치처럼 켰다 끌 수 있는 수준까지 바로 쓸 수 있다.