Docker Compose를 통해 여러 개의 컨테이너를 관리할 수 있다!테스트하려면 각 컨테이너를 하나씩 생성해야 한다.
docker compose up 명령어로 모든 서비스를 한 번에 시작할 수 있다.테스트 환경을 별도로 정의하고 아래와 같은 명령어로 관리할 수 있다.
# 테스트 환경 실행
docker compose up -d
# 테스트 실행
./run_tests
# 테스트 환경 정리
docker compose down
docker-compose.yaml 파일에 있는 애플리케이션들은 모두 같은 네트워크에 자동으로 연결1️⃣ 각 애플리케이션의 Dockerfile 작성
docker-compose.yaml 파일 작성docker compose up 명령어로 실행version: '3'
services:
web:
image: nginx:latest
ports:
- 80:80
volumes:
- ./web:/usr/share/nginx/html
depends_on:
- api
links:
- api:api
api:
image: java:latest
volumes:
- ./api:/app
ports:
- 8080:8080
environment:
- REDIS_HOST=redis
- MYSQL_HOST=mysql
- MYSQL_USER=root
- MYSQL_PASSWORD=password
- MYSQL_DATABASE=test
depends_on:
- mysql
- redis
links:
- mysql:mysql
- redis:redis
redis:
image: redis:latest
ports:
- 6379:6379
mysql:
image: mysql:latest
ports:
- 3306:3306
volumes:
- ./mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=test
- MYSQL_USER=root
- MYSQL_PASSWORD=password
version: Docker Compose의 버전 정의
services: 네 개의 서비스 정의
web 서비스는 Nginx 이미지를 사용하며, 포트 80번을 호스트 머신에 노출api 서비스는 Java 이미지를 사용하며, 포트 8080번을 호스트 머신에 노출redis 서비스는 Redis 이미지를 사용하며, 포트 6379번을 호스트 머신에 노출mysql 서비스는 MySQL 이미지를 사용하며 포트 3306번을 호스트 머신에 노출volumes: web 서비스는 현재 디렉토리 내 web 디렉토리를 컨테이너에 연결.
- api 서비스는 현재 디렉토리 내 api 디렉토리를 컨테이너에 연결.
mysql 서비스는 현재 디렉토리 내 mysql 디렉토리를 사용하여 MySQL 데이터를 영구적으로 저장.depends_on: 각 서비스 간의 의존성을 정의
- web 서비스는 api서비스에 의존
api 서비스는 mysql과 redis 서비스에 의존links: 각 서비스 간의 링크를 정의
- web 서비스는 api서비스에 링크.
api 서비스는 mysql과 redis 서비스에 링크.이 예제에서는 web 서비스와 api 서비스가 각각 독립적인 컨테이너로 실행된다.
web 서비스는 api 서비스에 의존하며, api 서비스는 mysql과 redis 서비스에 의존한다.
redis와 mysql 서비스는 각각 독립적인 컨테이너로 실행된다.
version: "3"
services:
service1:
# ...service1 설정
service2:
# ...service2 설정
networks:
# 네트워크 설정, 선택적
volumes:
# 볼륨 설정, 선택적
services:
web:
build:
context: . # Dockerfile 의 위치
dockerfile: Dockerfile # Dockerfile 파일명
container_name: testapp_web_1 # 생략하는 경우
# 자동으로 부여 docker run 의 --name 옵션과 동일
ports: "8080:8080" # docker run 의 -p 옵션과 동일
expose: "8080" # 호스트머신과 연결이 아니라
# 링크로 연결된 서비스 간 통신이 필요할 때 사용
networks: testnetwork # networks 를 최상위에 정의한다면 해당 이름을 사용
# docker run의 --net 옵션과 동일
volumes: .:/var/lib/nginx/html # docker run 의 -v 옵션과 동일
environment:
- APPENV=TEST # docker run 의 -e옵션과 동일
command: npm start # docker run 의 가장 마지막
restart: always # docker run 의 --restart 옵션과 동일
depends_on: db # 이 옵션에 지정된 서비스가 시작된 이후에 `web`서비스가 실행
links: db # Docker가 네트워크를 통해 컨테이너를 연결하도록 정의합니다.
# 컨테이너를 연결할 때 Docker는 환경 변수를 만들고
# 컨테이너를 알려진 호스트 목록에 추가하여 서로를 검색할 수 있도록 합니다.
deploy: # 서비스의 복제본 개수 등 지정
replicas: 3
mode: replicated
docker-compose.yml 파일에 선언된 볼륨만 docker-compose.yml 에서 사용가능version: "3.9"
services:
web:
# ...
volumes:
- README.md:/docs/README.md # 호스트의 README.md 파일을 컨테이너 내부 /docs/README.md에 마운트
- logvolume01:/var/log # 선언된 도커 볼륨 logvolume01을 컨테이너 내부 /var/log에 마운트
# ...
volumes:
logvolume01: {} # 도커볼륨 logvolume01 선언
default_${project} 형식의 네트워크가 자동으로 생성.docker-compose.yaml에서 재정의할 수 있다.docker-compose [COMMAND] [SERVICES...]의 형태로 사용하며, 특정 서비스(컨테이너)만 제어할 수 있다.
web, redis 중에 web만 기동하려면 아래와 같이 실행docker-compose up -d web
-서비스 실행 시 다음 순서로 진행
--build: 이미 빌드된 상태여도 강제로 빌드를 다시 진행.-d: 서비스를 백그라운드에서 실행.--force-recreate: 변경점이 없더라도 강제로 컨테이너를 재생성. 다시 말해, 기존 컨테이너를 종료하고 다시 생성.docker-compose down : 서비스 중지 및 삭제, 컨테이너와 네트워크 삭제--volume: 선언된 도커 볼륨도 삭제.docker-compose stop & docker-compose startstop: 실행 중인 서비스를 중지.start: 멈춰 있는 서비스를 시작.docker-compose ps : 현재 실행 중인 서비스 상태를 확인.docker-compose logs : 컨테이너 로그 확인-f : tail -f와 유사하게 로그를 실시간으로 확인.(follow)docker-compose exec : 실행 중인 컨테이너에 명령어를 실행docker-compose exec django ./manage.py makemigrations
docker-compose exec db psql postgres postgres
docker-compose run : 컨테이너를 기동시키고 특정 명령어를 실행한 후, 컨테이너를 종료 (일회성 명령어 실행 시 사용)docker-compose exec : 이미 실행 중인 컨테이너에서 명령어 실행docker-compose run: 컨테이너를 새로 기동하여 명령어 실행 후 종료# 이미 실행된 web 컨테이너에서 echo "hello world" 실행
docker-compose exec web echo "hello world"
# web 컨테이너를 새로 실행 -> echo "hello world" 실행 -> 컨테이너 종료
docker-compose run web echo "hello world"
cd ~/spring-boot-sample
# 백그라운드로 모드로 실행
docker-compose up -d
# 로그 확인
docker-compose logs -f
docker-compose up -d 명령어를 사용하여 백그라운드에서 Redis와 MySQL을 실행docker-compose logs -f 명령어로 실행된 서비스들의 로그 확인.

docker-compose down 실행 후 애플리케이션 실행docker-compose down 명령어로 Redis 서비스를 종료한 후 애플리케이션을 실행하면, Redis에 접속 불가.docker-compose up -d로 Redis 컨테이너를 다시 실행.

내가 실행하는 앱이 어떤 상태인지 Docker 모니터링을 통해 알아보고, 실행 과정을 기록한 로깅을 살펴보자 !!
도커 모니터링 : 컨테이너가 어떻게 돌아가고 있는지 지켜보는 것 docker stats 명령어를 사용하면 실행 중인 컨테이너의 자원 사용량을 실시간으로 확인할 수 있다.모니터링 정보를 통해 문제를 빨리 발견하고 해결 가능 !!
또한, 컨테이너를 효율적으로 관리하고 최적화할 수 있다 !!
docker stats : 컨테이너 모니터링의 시작점docker stats : Docker에서 제공하는 간단하고 실용적인 모니터링 도구docker stats 명령어를 터미널에 입력, 현재 실행 중인 모든 컨테이너의 상태를 한눈에 볼 수 있다.
CPU 사용률, 메모리 사용량, 네트워크 I/O, 디스크 I/O 등 여러 중요한 정보를 보여준다.
docker stats

특정 컨테이너의 상태만 보고 싶다면, 컨테이너의 이름이나 ID를 명령어 뒤에 추가
docker stats [컨테이너 이름 또는 ID]
htop : 시스템 모니터링의 필수 도구htop : 리눅스 시스템을 모니터링하는 강력한 도구.docker run --name test-tools -ti -d ubuntu:22.04
docker exec -ti test-tools /bin/bash
apt update; apt upgrade -y; apt install htop -y;

htop

exit
# test-tools라는 컨테이너가 실행 확인
docker stats

df :disk free의 약자로, 리눅스 시스템 전체의 디스크 사용량 확인 가능docker exec -ti test-tools /bin/bash
df -h
exit

du : 디렉토리 별로 사용 공간을 나타냄docker exec -ti test-tools /bin/bash
du -sh # 현재 디렉토리의 총 디스크 사용량을 GB 단위로 보여줌
du -h --max-depth=1 # 현재 디렉토리 한 단계 아래 디렉토리 까지만 사용량을 보여줌
exit

내가 만든 앱의 실행 과정을 기록한 로깅을 살펴보자 !!
docker run --name logs-test --rm -d ubuntu:22.04 /bin/bash -c 'while true; do date; sleep 1; done'
# logs-test 컨테이너의 로그를 전체 출력하기
docker logs logs-test
# logs-test 컨테이너의 로그를 tailing하기
docker logs -f logs-test
# 마지막 10줄부터 로그를 계속 보기
docker logs -f --tail 10 logs-test

docker inspect logs-test --format "{{.LogPath}}"
docker run -d \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=10 \
--name nginxtest \
--restart always \
-p 80:80 \
-p 443:443 \
nginx:latest
# Container 의 log file 크기와 개수 제한
docker run -d \
--log-driver json-file \
--log-opt max-size=1m \
--log-opt max-file=5 \
--name nginxtest \
--restart always \
-p 80:80 \
-p 443:443 \
nginx:latest
# 로그 보기
docker logs -f nginxtest

docker-compose.yml 파일에서 로그 설정을 추가하여 로그 파일의 크기와 개수를 제한할 수 있다.services:
app:
...
logging:
driver: 'json-file'
options:
max-size: '10m'
max-file: '10'
docker stop nginxtest
docker container rm nginxtest
출처 : [TeamSparta]