도커 컴포즈란?
도커 컴포즈는 단일 서버에서 여러개의 컨테이너를 하나의 서비스로 정의해 컨테이너의 묶음으로 관리할 수 있는 작업 환경을 제공하는 관리 도구이다. 따라서 도커 컴포즈를 통해 한 번에 컨테이너를 실행하거나 중지할 수 있다. 특히 복잡한 애플리케이션을 운영할 때, 여러 개의 서비스가 서로 연관되어 있는 경우 Docker Compose를 사용하면 더 효율적으로 관리할 수 있다.
도커 컴포즈 사용 이유
여러 개의 컨테이너를 사용할 때 발생할 수 있는 문제 중 하나는 설정 불일치이다. 예를 들어, 컨테이너의 데이터베이스와 웹 서버가 각각 다른 설정을 가지고 있을 때 설정이 일관되지 않아 오류가 발생할 수 있다. 각 컨테이너의 버전, 환경 변수, 네트워크 설정 등이 달라지면, 예상하지 못한 동작을 초래할 수 있다.
또한 도커 컴포즈를 사용하지 않는다면, 이를 테스트하려면 각 컨테이너를 하나씩 생성해야한다. 예를 들어, 웹 어플리케이션을 테스트 하려면 웹 서버 컨테이너, 데이터베이스 컨테이너 두 개의 컨테이너를 각각 생성해야한다.
이렇게 여러개의 컨테이너를 일일이 실행하기에는 번거롭다.
이러한 문제를 해결하기 위해 Docker Compose를 사용하여 각 컨테이너의 설정(버전, 환경 변수, 네트워크 등)을 하나의 docker-compose.yml 파일에 정의하고 이를 통해 설정의 일관성을 유지할 수 있다.
도커 컴포즈 핵심 구성 요소
1️⃣ 서비스(Service)
Docker Compose에서 실행될 각 컨테이너들을 정의한다. 예를 들어, 웹 애플리케이션을 실행하는 웹 서버나 데이터베이스를 실행하는 컨테이너가 서비스로 정의될 수 있다. 서비스는 각각 독립적인 설정을 가지고 있다.
services:
web:
image: nginx
ports:
- "8080:80"
db:
image: postgres
environment:
POSTGRES_PASSWORD: example
위의 예에서,web과 db는 두 개의 서비스이다.
2️⃣ 네트워크(Network)
Docker Compose는 기본적으로 모든 서비스를 동일한 네트워크에 연결한다. 즉, 기본 네트워크를 생성하고 그 안에 모든 서비스를 배치하게 된다. 서비스들은 이 네트워크를 통해 서로 통신할 수 있다.
하지만 때때로 특정 서비스들이 다른 서비스들과 독립적인 네트워크에 속해야 할 때가 있다. 이때는 사용자 정의 네트워크를 설정할 수 있다.
services:
web:
image: nginx
networks:
- webnet
db:
image: postgres
networks:
- webnet
cache:
image: redis
networks:
- cache_network
networks:
webnet:
cache_network:
위의 예에서, web과 db는 webnet이라는 네트워크에 속하며, cache는 cache_network라는 다른 네트워크에 속한다. 이렇게 사용자 정의 네트워크를 사용하면 네트워크 간에 독립성을 유지할 수 있다.
3️⃣ 볼륨(Volume)
컨테이너와 호스트 시스템 간에 데이터를 지속적으로 공유하거나 저장할 때 사용된다. 예를 들어, 데이터베이스에서 생성된 데이터를 컨테이너가 종료되거나 삭제되더라도 유지하고 싶을 때 볼륨을 사용한다. 볼륨은 Docker가 관리하는 외부 스토리지 시스템으로, 데이터를 컨테이너 외부에 저장해 컨테이너가 재시작되거나 삭제되어도 데이터를 보존할 수 있다.
services:
db:
image: postgres
volumes:
- db_data:/var/lib/postgresql/data
web:
image: nginx
volumes:
- ./html:/usr/share/nginx/html
volumes:
db_data:
위 예시에서는 db 서비스에서 db_data라는 볼륨을 사용해 데이터를 /var/lib/postgresql/data 경로에 저장하고 있다. web 서비스에서는 로컬 ./html폴더를 /usr/share/nginx/html 경로에 마운트하여 웹 서버에서 사용할 HTML 파일을 공유한다.
* db_data: Docker가 자동으로 관리하는 볼륨이다.
도커 컴포즈 사용해보기
1️⃣ docker-compose.yml 파일 생성
도커 컴포즈를 사용하려면 먼저 docker-compose.yml 파일을 생성해야 한다. 이 파일은 여러 개의 컨테이너를 정의하고, 네트워크, 볼륨, 환경 변수 등을 설정하는 데 사용된다.
version: '3'
services:
web:
image: nginx:latest
container_name: webserver
depends_on:
- db
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
networks:
- app-network
db:
image: mysql:5.7
container_name: mysql-db
environment:
MYSQL_ROOT_PASSWORD: example
ports:
- "3306:3306"
volumes:
- db-data:/var/lib/mysql
networks:
- app-network
# 사용자 지정 네트워크 정의
networks:
app-network:
driver: bridge
# 데이터베이스 데이터가 저장될 볼륨 정의
volumes:
db-data:
이 파일에서는 web과 db라는 두 개의 서비스를 정의하고 있다. web은 nginx 이미지를 사용하고, db는 mysql 이미지를 사용한다.
- version : 도커 컴포즈 파일의 버전을 정의한다. version: '3'은 최신 기능을 지원하는 안정적인 버전으로, 일반적으로 사용된다.
- image: 사용할 도커 이미지 이름과 태그를 지정한다. 여기서는 nginx:latest를 사용하여 최신 버전의 Nginx 이미지를 사용한다.
- container_name: 컨테이너의 이름을 설정한다.
- depends_on: 한 서비스가 다른 서비스가 준비된 후에 실행되도록 의존성을 설정하는 방법이다. 예를 들어, web이 db가 준비되기 전에 실행되지 않도록 설정하려면 depends_on을 사용할 수 있다.
- ports: 호스트와 컨테이너 간의 포트를 매핑한다. "8080:80"은 호스트의 8080 포트를 컨테이너의 80 포트로 매핑한다.
- environment: 환경 변수를 정의한다.
❗️ Tip
환경 변수 파일(.env)을 사용할 수 있다.
먼저, 프로젝트 루트 디렉터리에 .env 파일을 만든다.
Docker Compose 파일에서 ${변수명} 형식으로 .env 파일의 변수를 사용할 수 있다.
docker-compose.yml 내부에서 환경 변수를 직접 지정할 수도 있지만, .env 파일을 사용하면 설정을 관리하기가 훨씬 쉬워진다.
version: '3.8' services: db: image: mysql:latest environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
2️⃣ 도커 컴포즈로 서비스 시작
docker-compose.yml 파일을 만든 후, 터미널에서 해당 파일이 위치한 디렉토리로 이동하여 다음 명령어로 서비스를 시작한다
docker-compose up
이 명령어는 docker-compose.yml 파일에 정의된 모든 서비스를 한 번에 시작한다. 예를 들어, 위의 예시에서는 nginx 웹 서버와 mysql 데이터베이스가 동시에 시작된다.
3️⃣ 백그라운드에서 실행
서비스를 백그라운드에서 실행하려면 -d 옵션을 추가한다
docker-compose up -d
이 명령어를 실행하면 서비스가 백그라운드에서 실행되며, 터미널을 계속 사용할 수 있다.
4️⃣ 서비스 상태 확인
실행 중인 서비스를 확인하려면 다음 명령어를 사용한다
docker-compose ps
이 명령어는 현재 실행 중인 컨테이너의 상태를 보여준다.
5️⃣ 서비스 중지
실행 중인 서비스를 중지하려면 다음 명령어를 사용한다
docker-compose down
이 명령어는 docker-compose.yml 파일에서 정의된 모든 컨테이너를 중지하고, 네트워크와 볼륨 등도 삭제한다.
도커 컴포즈 미사용 vs 사용
Docker Compose를 사용하지 않았을 때
# 웹 서버 실행
docker run -d --name web --network app-network nginx:latest
# 데이터베이스 실행
docker run -d --name db --network app-network mysql:latest
- 각 컨테이너를 수동으로 실행해야 하며, 모든 설정을 개별적으로 관리해야 한다.
- 컨테이너 간의 네트워크 설정이나 환경 변수 관리가 번거롭고 일관성 있게 유지하기 어렵다.
- 여러 서비스를 동시에 시작하거나 중지하는 작업이 불편하다.
Docker Compose를 사용했을 때
docker-compose up -d
- docker-compose.yml 파일에 모든 설정을 정의하고, docker-compose up 명령으로 모든 서비스를 한 번에 실행할 수 있다.
- 여러 컨테이너의 네트워크와 설정을 한 곳에서 관리할 수 있어 일관성 있게 유지된다.
- 컨테이너의 상태를 한 번에 관리할 수 있다.
Docker Compose, Docker Swarm, Kubernetes 비교

도커 컴포즈는 주로 로컬 환경에서 사용 된다. 따라서 프로덕션 환경에서는 도커 컴포즈가 아닌, 다른 오케스트레이션 도구들이 사용된다.
이유는, 대규모 시스템에서는 수천 개의 컨테이너를 관리해야 할 수 있기 때문에 트래픽 변화에 맞춰 컨테이너를 자동으로 확장하거나 축소를 해야하한다. 또한, 서비스 중단 없이 자동으로 복구하거나 컨테이너를 교체를 해야하기 때문이다.
* 프로덕션 환경: 실제 서비스가 운영되는 환경을 의미한다. 즉, 사용자가 접속하고 실제로 서비스를 이용하는 환경이다.
* 오케스트레이션: 컨테이너를 자동으로 배포, 관리, 확장하는 과정을 의미한다.
오케스트레이션 도구
1️⃣ 도커 스웜
도커에서 제공하는 기본 오케스트레이션 도구로, 여러 대의 서버를 하나의 클러스터로 묶고, 컨테이너를 쉽게 배포하고 관리할 수 있도록 도와준다. 도커 엔진에 내장되어 있어서 간단하게 "docker swarm init" 명령어로 스웜 모드로 전환할 수 있다.
따라서 간단하고 빠른 배포, 자동 로드밸런싱과 같은 기본적인 오케스트레이션 기능을 제공한다. 그러나 기능은 상대적으로 단순하다.
2️⃣ 쿠버네티스
가장 강력한 오케스트레이션 툴로, 대규모 분산 시스템을 관리하기에 적합하다. 자동 배포, 확장, 자원 관리, 로드밸런싱, 장애 복구, 자동 롤백 등 다양한 고급 기능을 제공하며, 수천 대의 노드까지 확장이 가능하다. 따라서 대규모 클러스터에서 높은 신뢰성과 확장성을 제공한다. 쿠버네티스는 복잡한 분산 시스템을 관리하고 최적화하는 데 유리하다.
* 클러스터: 여러개의 텀퓨터를 하나의 시스템처럼 묶어서 관리하는 것을 말한다. 즉, 하나의 클러스터로 묶인 여러 서버들이 서로 연동되며 하나의 시스템처럼 동작하는 환경을 의미한다.
정리
도커 컴포즈, 도커 스웜, 쿠버네티스는 모두 컨테이너 관리와 오케스트레이션 도구이지만, 각기 다른 목적과 기능을 가지고 있다.
도커 컴포즈는 주로 로컬 개발 환경에서 사용되며, 여러 개의 컨테이너를 간단히 정의하고 동시에 실행할 수 있도록 도와준다.
도커 스웜은 도커에서 기본 제공하는 오케스트레이션 도구로, 여러 대의 도커 엔진을 하나의 클러스터처럼 묶어 관리할 수 있다. 간단하고 빠른 배포와 자동 로드밸런싱을 지원하며 도커와의 호환성이 뛰어나지만, 쿠버네티스보다는 기능이 적고 복잡한 환경에서는 한계가 있다.
쿠버네티스는 가장 강력한 오케스트레이션 도구로, 자동 배포, 자원 관리, 로드밸런싱, 장애 복구 기능을 제공한다. 대규모 클러스터에서 높은 신뢰성과 확장성을 제공하며, 복잡한 시스템을 효율적으로 관리할 수 있다. 하지만 설정과 관리가 복잡하고, 대규모 환경에 적합하다.
마무리
Docker Compose는 여러 개의 서비스를 효율적으로 관리하고 설정할 수 있는 강력한 도구이다. 여러 개의 컨테이너를 사용하는 복잡한 시스템에서 Docker Compose를 사용하면 설정 불일치 문제를 해결하고, 관리가 쉬워진다. docker-compose.yml 파일을 작성하고, 이를 기반으로 애플리케이션을 배포하고 실행하는 것이 매우 간편해진다.
Docker Compose를 사용하면 로컬 개발 환경뿐만 아니라, 프로덕션 환경에서도 여러 서비스들을 쉽게 설정하고 관리할 수 있어, 많은 개발자들에게 유용한 도구이다.