2025. 3. 25. 14:03ㆍDocker
Docker Compose 는 여러 컨테이너로 구성된 애플리케이션을 손쉽게 정의하고 실행할 수 있도록 도와주는 도구이다. 단일 명령어로 여러 컨테이너를 시작 ,중지, 관리할 수 있어 개발 및 운영 환경에서 매우 유용한 도구이다.
Docker Compose?
멀티 컨테이너 관리 도구 : 하나의 애플리케이션이 여러 개의 컨테이너(ex: Web Server, Database, Cache Sever 등)로 구성될 떄 이들을 한 번에 정의하고 실행할 수 있도록 한다.
개발 및 테스트 환경: 복잡한 환경을 빠르게 구성하고 쉽게 재현할 수 있어 로컬 개발 환경이나 CI CD 파이프라인에 자주 사용된다.
YAML 기반 설정: 애플리케이션 구성 요소(컨테이너)를 YAML 파일에 정의하여 각 서비스의 이미지, Port, Volume, Network 등의 설정을 한다.
YAML Anchor & Aliases: 중복되는 설정을 재사용하기 위해서는 &와 * 기능을 사용할 수 있다.
그리고 기본 형식인 docker-compse.yml 외에도 추가 설정 파일을 - f 옵션을 지정해 여러 파일을 병합하여 사용할 수 있다.
기본 파일명은 docker-compose yml 이다.
- version : Compose 파일의 문법 Version 을 지정한다.
- service : 실행할 컨테이너들을 정의하는 부분이다.
- image : 사용할 Docker 이미지를 지정한다
- build :Dockerfile을 사용하여 이미지를 빌드할 경우 설정한다.
- ports :호스트와 컨테이너 간 Port 매핑을 지정한다.
- volumes : 호스트와 컨테이너 간 파일 또는 디렉토리 공유를 설정한다.
- environment: 환경 변수 설정
환경 변수와 .env 파일 활용
Compose 파일 내에서 ${VARIABLE} 형식으로 환경 변수를 사용할 수 있으며 이를 통해 환경에 따라 설정을 다르게 적용할 수 있다.
.env 파일 : Compose 실행 디렉토리에 .env 파일을 두면 해당 파일 내 변수들을 자동으로 로드해 치환할 수 있다.
- depends_on : 서비스 간의 의존 관계를 설정하여, 어떤 서비스가 먼저 시작되어야 하는 지를 제어할 수 있다.
deponds_on 은 단순히 컨테이너 시작 순서를 제어하지만 실제 서비스의 준비를 (ex: 데이터베이스가 완전히 준비됨)을 보장하지는 않는다.
대안방안으로는 컨테이너 내부에서 재시도 로직을 구현하거나 외부 도구 (ex: wait-for-it script) 를 사용할 수 있다.
- networks : 서비스 간 통신을 위한 네트워크를 정의한다
- volumes : docker 를 종료해도 데이터를 저장하기 위해서 Docker volumes 를 정의한다.
ex:
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
app:
image: node:18
working_dir: /usr/src/app
volumes:
- ./app:/usr/src/app
command: ["node", "server.js"]
environment:
- NODE_ENV=production
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: example
volumes:
- db-data:/var/lib/mysql
volumes:
db-data:
Docker Compose 명령어
docker compose up - 컨테이너 시작
-d option을 붙이면 background 실행이 가능하다
docker compose down - 컨테이너 중지
docker compose logs - 컨테이너 로그 확인
docker compose up -d 서비스명 - 서비스별 실행
docker compose -f web.yml up -d - 구성파일 지정
기본 파일명이 아닌 경우 -f 옵션을 지정할 수 있다.
Build Option
Compose 파일에서 build option을 사용하면 미리 만들어진 이미지 대신에 로컬에 있는 Dockerfile 을 사용해 이미지를 빌드 할 수 있다. 이를 통해 컨테이너가 실행되기 전에 애플리케이션 코드나 의존성을 포함한 커스텀 이미지를 생성할 수 있다.
build contxt
빌드를 수행할 디렉토리를 지정한다.
이 경로 내에 Dockerfile 과 관련된 소스 파일들이 있어야 한다.
build:
context: ./app
-> ./app 디렉토리 내에 Dockerfile 이 존재한다면 이 디렉토리를 기준으로 빌드를 수행한다.
Dockerfile
기본적으로 Dockerfile 은 context 내의 Dockerfile 을 사욯하지만 만약 파일명이 다르거나 다른 위치에 있다면 옵션을 사용해서 지정할 수 있다.
args
빌드 시 사용할 인자 (arguments)를 지정할 수 있다.
Dockerfile 내에서 arg 명령어로 선언된 인자에 값을 전달할 수 있다.
build:
context: .
args:
APP_ENV: production
→ Dockerfile 내에서 ARG APP_ENV로 선언되어 있으면, 빌드 시 production 값이 전달된다.
Scaling
스케일링 기능은 동일한 서비스(컨테이너)의 Replica를 여러 개 실행하여 부하 분산이나 고가용성을 구현할 때 사용된다. 동일한 애플리케이션 인스턴스를 여러 개 생성하여 요청을 분산 처리할 수 있다.
# --scale <서비스이름>=<컨테이너갯수>
docker compose up --scale app=3
-> app 서비스의 컨테이너를 3개 실행한다.
https://docs.docker.com/compose/gettingstarted/
Quickstart
Check out this tutorial on how to use Docker Compose from defining application dependencies to experimenting with commands.
docs.docker.com
작동 방식 및 주의사항
- 동일한 서비스 인스턴스
스케일링된 각 컨테이너는 동일한 이미지와 설정을 기반으로 생성된다.
내부적으로는 각 컨테이너가 고유의 ID를 갖지만 동일한 네트워크와 볼륨 설정을 공유할 수 있다.
- 포트 매핑
단일 호스트의 포트를 여러 컨테이터를 매핑하는 경우 충돌이 발생할 수 있기 때문에 주의해야한다. 보통 로드 밸런서를 사용하거나 각 컨테이너의 내부 포트를 사용하고 외부에서는 Proxy 를 통해 라우팅하는 방식으로 해결한다.
- 네트워킹
Compose 는 기본적으로 모든 서비스들을 같은 사용자 정의 네트워크에 포함시킨다.
스케일링된 서비스들은 이 네트워크 내에서 서로 통신할 수 있으며, 예를 들면 데이터 베이스와 여러 앱 컨테이너가 문제없이 연동로딜 수 있디.
- 상태 관리
Stateless Service (ex: Web Server)는 스케일링에 적합하다
반면 Stateful 서비스는 데이터 일관성과 세션 관리 등의 추가적인 고려사항이 필요하다.
- 재시작 및 업데이트
스케일링된 서비스 중 하나에 업데이트가 필요한 경우 롱링 업데이트나 서비스 재시작 전략을 고려해야한다.
예시: 웹 애플리케이션 스케일링
Compose 파일 내에서 app이라는 서비스를 정의했다고 가정할 때:
version: '3.8'
services:
app:
build:
context: ./app
ports:
- "3000:3000"
environment:
- NODE_ENV=production
실행 명령어
docker compose up --scale app=3 -d
app 서비스를 3개의 복제본으로 백그라운드 실행한다.
app 서비스가 web application 이라면 이를 통해 여러 인스턴스가 동시에 요청을 처리할 수 있다.
Docker Compose 에서는 서비스 이름만으로 컨테이너 간 통신이 가능하다.
= Docker Compose 의 내장 네트워크 기능 덕분에 가능하다.
Docker Compose는 기본적으로 하나의 사용자 정의 Bridge Network 를 만들어서 그 네트워크 안의 서비스들기리는 자동으로 DNS 이름 기반을 통신이 가능하다.
services:
web:
image: nginx
app:
image: my-app
위와 같이 정의해도
ping web
curl http://we
으로 핑을 보내거나 접속할 수 있다.
내부적으로는 Docker COmpose 가 web과 app을 같은 네트워크로 묶고 이 컨테이너 이름이 Hostname으로 등록된다. 그리고 Docker 자체적으로 DNS가 이를 알아서 처리한다.
-> 디테일하게 살펴보면
Docker Compose 는 docker-compose up을 할때 자동을 user-defined brdige network 를 생성한다.
이 때 Compose 에서 정의된 서비스들은 자동으로 이 네트워크에 붙게 된다.
docker inspect myproject_web_1
"Networks": {
"myproject_default": {
"Aliases": [
"web",
"myproject_web_1"
],
...
}
}
위 출력결과를 보면 web 이라는 이름이 hostname 이자 DNS 이름으로 등록된 것을 확인할 수 있다.
이처럼 Docker 는 user-defined brdige network 에 대해서 내장 DNS 서버를 제공하고 이 DNS 서버는 네트워크 안의 컨테이너 이름 -> ip 주소로 자동 매핑해준다.
Healthcheck Option
healthcheck option 을 사용하면 컨테이너가 정상적으로 작동하는 지 주기적으로 검사 할 수 있다.
services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
+ Configs & Secrets
Configs : Docker Swarm mode 에서 Compose 파일로 애플리케이션 구성을 관리할 때 사용한다.
Secrets : 민감한 정보를 안전하게 저장하고 서비스를 주입할 수 있도록 도와준다.
ex:
secrets:
db_password:
file: ./db_password.txt
services:
db:
image: mysql:8
secrets:
- db_password
'Docker' 카테고리의 다른 글
Docker Architecture (0) | 2025.03.19 |
---|---|
컨테이너 가상화 (0) | 2025.03.18 |