지금까지 도커 컨테이너를 많이 띄우다보면 드는 생각이 하나 있다.
"각각의 컨테이너가 서로 유기적으로 작동하게 만들 수는 없나?"
있다. 방법이.
Docker Compose란?
여러 도커 컨테이너를 정의하고 실행하기 위한 도구이다.
YAML 파일을 사용하여 애플리케이션의 서비스, 네트워크, 볼륨 등을 구성하고,
단일 명령어로 이 모든 서비스를 시작하거나 종료 할 수 있게 해준다.
도커 컴포즈의 장점
1. 멀티 컨테이너 애플리케이션 정의 : 여러 컨테이너, 볼륨, 네트워크를 관리해야 하는 복잡한 애플리케이션을 쉽게 관리 할 수 있다. 각 컴포넌트를 모듈화하여 관리 할 수 있으며, 종속성과 실행 순서를 명확하게 정의 할 수 있다.
2. 환경 일관성 보장: docker-compose.yml 파일을 통해 개발, 스테이징(테스트), 프로덕션 환경 간 설정의 차이를 최소화 할 수 있다.
3. 간편한 실행 및 종료: docker-compose up 명령을 통해 정의된 모든 컨테이너를 한 번에 시작하고,
docker-compose down 명령을 통해 모든 컨테이너를 한번에 종료 할 수 있다.
다음으로 도커 컴포즈의 요소에 대해 설명하겠다.
도커 컴포즈(Docker compose) 기능 요소
- build: 직접 빌드하며 사용 할 때 사용
- context: 빌드를 진행 할 폴더 경로를 지정
- dockerfile: 사용 할 Dockerfile의 이름과 경로를 지정
build:
context: ./dir
dockerfile: Dockerfile
- image: 사용할 Docker 이미지를 지정한다. 빌드하지 않고 이미 존재하는 이미지를 사용 할 때
image: node:22-slim
- ports: 호스트 컨테이너 간의 포트 매핑을 한다.
ports:
- "5000:5000"
- environment: 컨테이너 내에서 사용 할 환경 변수를 지정
environment:
- FLASK_ENV=development
- DATABASE_URL=mysql://user:password@db/mydatabase
- volumes: 호스트와 컨테이너 간 파일 시스템을 마운트
volumes:
- ./hostapp:/containerapp
- depends_on: 컨테이너 간 의존성을 지정한다. 이것을 통해 특정 서비스가 db서비스가 시작된 후에 시작하게끔 지정 할 수 있다.
depends_on:
- db
- networks: 서비스가 연결될 네트워크를 지정
networks:
- front-network
- restart: 컨테이너 재시작 정책을 지정. always / on-failure / unless-stopped 등의 값으로 지정 할 수 있음
restart: always
위의 요소로만 하나의 서비스를 간략하게 나타내면 이렇게 할 수 있다.
webapp:
build:
context: ./app
dockerfile: Dockerfile
ports:
- "5000:5000"
environment:
- NODE_ENV=production
volumes:
- ./app:/usr/src/app
depends_on:
- db
networks:
- back-tier
restart: always
전역으로 정의하여 여러 컨테이너에서 공통으로 사용 하는 요소들을 설명하겠다.
- 네트워크(networks): 서비스 간 통신 할 네트워크를 정의한다.
networks:
app-network:
- 볼륨(volumes): 데이터 저장소를 정의, 컨테이너에 영구적으로 저장하거나 컨테이너 간 공유 할 수 있게 한다.
volumes:
db-data:
- 컨피그 (Configs): 설정 파일이나 환경 설정을 관리한다.
configs:
https-request:
- 시크릿(secrets): 중요한 데이터(API키 또는 SSL인증서 등)을 안전하게 저장하고 서비스에 제공한다.
secrets:
api-key:
전역으로 선언한 요소와 다양한 컨테이너를 연결한 전체의 도커 컴포즈 파일을 간략하게 나타내보겠다.
(실제로 작동하진 않는다)
version: '3.7' # Docker Compose 버전
# 전역으로 사용할 것 정의
volumes: # 볼륨 정의
db-data:
networks: # 네트워크 정의
app-network:
configs: # 설정 정의
https-request:
external: true
secrets: # 시크릿 정의
api-key:
external: true
# 서비스 정의
services:
webapp: # 웹 애플리케이션 서비스
build: # 직접 이미지를 빌드하여 사용
context: ./app
dockerfile: Dockerfile
ports:
- "5000:5000"
environment:
- NODE_ENV=production
volumes:
- ./app:/usr/src/app
depends_on: # db 서비스가 시작해야 해당 서비스를 실행
- db
networks:
- app-network
restart: always
db: # 데이터베이스 서비스
image: postgres:13 # 기존 빌드된 이미지를 사용
environment:
- POSTGRES_USER=exampleuser
- POSTGRES_PASSWORD=examplepass
- POSTGRES_DB=exampledb
volumes:
- db-data:/var/lib/postgresql/data
networks:
- app-network
configs:
- source: https-request
secrets:
- source: api-key
restart: always
도커 컴포즈 명령어
- docker-compose up: docker-compose.yml 파일에 정의된 모든 서비스를 빌드하고 시작
- docker-compose down: 실행 중인 모든 서비스를 중지하고, 네트워크와 볼륨을 포함한 모든 리소스를 정리
- docker-compose ps: 현재 실행 중인 서비스를 목록으로 표시
- docker-compose logs: 현재 실행 중인 서비스의 로그를 출력
클라우드에서 도커 컴포즈를 쓰면 장점도 있지만 무작정 쓰기엔 단점도 있다.
따라서 도커 컴포즈를 사용하기에 앞서 고려해볼만한 사항이 있다.
"도커 컴포즈를 써야만 하는가?"
만약 도커 컴포즈로 특정 애플리케이션을 구성하려 할 때,
프론트, 백엔드, db가 서로 유기적으로 작동되는 컴포즈를 만든다고 생각해보자.
먼저 db가 잘 작동하도록 애플리케이션을 세팅하고, 백엔드를 구성한 뒤, 프론트가 작동하도록 하여
컴포즈 파일을 작성하고 실행한다.
운이 좋게 해당 컴포즈로 실행한 애플리케이션이 유기적으로 잘 동작하였다.
근데 만약 백엔드에서 네트워크, 볼륨, 환경변수, 시크릿과 같은 의존성이 바뀐다면?
그것과 연결되어있는 db와 프론트에서도 그에 맞게 의존성을 변경해줘야 제대로 동작 할 것이다.
또한, 성능 측면에서도 바라보면,
프론트, 백엔드, db에서 필요한 자원(성능)이 각각 1이라고 해보자.
(성능이 크게 상관없는 데스크탑이나 맥북에서는 고려하지 않아도 되겠지만)
도커 컴포즈를 사용한다면 3의 성능이 필요할 것이다.
하지만 클라우드에서 가상 서버를 사용한다면
각각 1인 서버를 3개 사용하는 비용보다, 성능이 3인 1개의 서버를 사용하는 게 비용이 더 클 수도 있다.
또한, 만약 백엔드에서 사용량이 많아져 2의 성능을 필요로하는데 서버의 여유자원이 없다면?
그럼 해당 서버는 프론트, 백엔드, db 모두 셧다운이 되어버릴 것이다.(연대 책임)
오히려 한곳에 뭉쳐놓은것이 서로의 발목을 잡는 형태가 되는 것이다.
그래서 도커 컴포즈가 무조건 만능인 것이 아니다.
그래서 만약 프로젝트에서 도커 컴포즈를 사용한다면, 위의 고려사항을 충분히 고려해보길 바란다.
도커 컴포즈 사용에 대한 고려사항
- 서비스 간 의존성 관리
- 리소스 할당 및 확장성
- 비용 관리
- 장애 대응
이상으로 도커 컴포즈에 대한 글을 마치도록 하겠다.
'Docker' 카테고리의 다른 글
[Docker] 5. Overlay FS & Storage (0) | 2024.09.14 |
---|---|
[Docker] 4. 도커 이미지 레이어(Image Layer) (1) | 2024.09.13 |
[Docker] 3. 도커 파일 멀티스테이지 빌드(Multi-stage build) (1) | 2024.09.13 |
[Docker] 2.도커 허브 (0) | 2024.09.13 |
[Docker] 1. 도커 파일 작성 & 컨테이너 실행하기 (0) | 2024.09.12 |