
Docker는 컨테이너로 구성되고 컨테이너는 이미지로 구성된다.
즉, 컨테이너와 이미지를 관리하는데 이미지가 여러개인 경우가 있을 수 있다.
이때, Docker Compose를 이용하면 더 쉽게 관리할 수 있다.
Docker의 Compose란, 여러 개의 Docker 컨테이너들을 하나의 서비스로 정의하고 구성해 하나의 묶음으로 관리할 수 있게 도와주는 툴이다.
기존에 Dockerfile을 사용하여 커스텀한 컨테이너와 이미지를 만들었다면, 하나의 이미지가 아니라 여러 이미지를 Docker Compose를 사용하여 구현할 수 있다.
Docker Compose를 사용하는 것엔 크게 2가지 이유가 있다.
1. 여러개의 컨테이너를 관리할 수 있다.
기존에 하나의 이미지만 빌드하고, 실행하는 컨테이너가 아니라 여러개의 이미지를 한번에 실행시키고, 관리할 수 있다.
2. 명령어를 간소화시킬 수 있다.
Dockerfile에 대해 docker build -t ... 등의 명령어는 꽤나 복잡하다.
하지만, Docker Compose파일을 사용하면 이를 간소화할 수 있다.
Docker Compose는 Dockerfile과 마찬가지로 파일을 따로 생성하고, 실행할 수 있다.
아래와 같이 compose.yml 파일을 생성하면 compose 파일을 사용할 수 있다.

터미널에서 docker compose up -d라는 명령어로 실행할 수 있다.
docker compose up -d
compose.yml 파일에서는 컨테이너들을 services라고 명명한다.
그래서 다음과 같이 사용할 수 있다.
services:
[컨테이너 이름]:
container_name: [컨테이너 이름]
image: [이미지]
environment:
[환경변수]: [정의]
volumes:
- [호스트 파일 경로]:[컨테이너 내부 파일 경로]
build: [빌드 경로]
ports:
- [호스트 포트]:[컨테이너 포트]
Docker Compose는 여러개의 컨테이너를 한번에 띄울 수 있게 해준다.
다음과 같이 사용할 수 있다.
services:
[컨테이너 이름1]:
container_name: [컨테이너 이름1]
image: [이미지]
environment:
[환경변수]: [정의]
volumes:
- [호스트 파일 경로]:[컨테이너 내부 파일 경로]
build: [빌드 경로]
ports:
- [호스트 포트]:[컨테이너 포트]
[컨테이너 이름2]:
container_name: [컨테이너 이름2]
image: [이미지]
environment:
[환경변수]: [정의]
volumes:
- [호스트 파일 경로]:[컨테이너 내부 파일 경로]
build: [빌드 경로]
ports:
- [호스트 포트]:[컨테이너 포트]
컨테이너를 짓는 곳에 맞춰서 하나 더 똑같이 입력해주면 된다.
일반적으로 백엔드 서버와 데이터베이스 서버를 띄운다고 하면 같이 띄울 수 있다.
Backend는 DataBase가 연결된 상태에서 실행되어야 한다.
BE가 DB의 정보를 가져오는 경우가 많은데, 이때 BE를 서버에 띄우기 전에 DB를 띄워야 한다. compose.yml에 BE를 실행하기 전 DB가 잘 띄워져 있는지 확인하려면 다음과 같이 작성할 수 있다.
services:
my-server:
build: .
ports:
- 8080:8080
depends_on: # my-db의 컨테이너가 생성되고 healthy하다고 판단되면, 컨테이너를 생성
my-db:
condition: service_healthy
my-db:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: pwd1234
MYSQL_DATABASE: mydb
ports:
- 3306:3306
healthcheck:
test: [ "CMD", "mysqladmin", "ping" ] # MySQL이 healthy 한 지 판단할 수 있는 명령어
interval: 5s # 5초 간격으로 체크
retries: 10 # 10번까지 재시도
즉, depends_on과 healthycheck를 통해 my-db 서버가 띄워져 있는지 판단하고 띄워져 있다면 my-server 컨테이너를 생성한다.
각 컨테이너는 고유의 ports를 가진다.
아래와 같은 연결이 있다고 가정하면 host 컴퓨터에서 3306포트와 spring 컨테이너에서 보는 3306 포트는 다르다.
mysql 포트는 host의 3306과 컨테이너의 3306으로 연결되기 때문에 spring 컨테이너도 mysql의 3306 포트로 연결해야 한다. 이때, host를 localhost가 아닌 컨테이너 명을 사용하면 된다.
예를들어, localhost:3306/mydb가 아닌 my-db:3306/mydb로 말이다.