docker 서버에서 여러 container를 프로젝트 단위로 묶어서 관리.
docker-compsoe.yml YAML 파일을 통해 명시적 관리
프로젝트 단위로 도커 네트워크와 볼륨 관리
프로젝트 내 서비스 간 의존성 정의 가능
프로젝트 내 서비스 디스커버리 자동화
손 쉬운 컨테이너 수평 확장
/fastcampus-devops/3-docker-kubernetes/4-docker-compose/build$ docker-compose up
[+] Running 3/3
⠿ Network build_default Created 0.1s
⠿ Container build-redis-1 Created 0.1s
⠿ Container build-web-1 Created
브릿지 네트워크가 default로 생성
build_default 에서 build는 프로젝트 명으로 명시하지 않으면 디렉토리를 프로젝트 명으로 사용함.
build-redis-1 redis는 서비스 명, 1은 container의 index
$ docker-compose -p my-project up -d
-d: background로 실행. docker run과 동일(detached)
$ docker-compose ls
NAME STATUS
my-project running(2)
$ docker-compose ls -a
NAME STATUS
build exited(2)
my-project running(2)
docker-compose check
위치 변경됨
fastcampus-devops/3-docker-kubernetes/4-docker-compose/wordpress$ docker-compose up -d
[+] Running 4/4
⠿ Network wordpress_wordpress Created 0.1s
⠿ Volume "wordpress_db" Created 0.0s
⠿ Container wordpress-db-1 Started 0.7s
⠿ Container wordpress-wordpress-1 Started
$ docker compose down
[+] Running 3/3
✔ Container wordpress-wordpress-1 Removed 1.3s
✔ Container wordpress-db-1 Removed 2.1s
✔ Network wordpress_wordpress Removed
container, network 삭제
$ docker-compose up -d
[+] Running 3/3
⠿ Network wordpress_wordpress Created 0.2s
⠿ Container wordpress-db-1 Started 0.8s
⠿ Container wordpress-wordpress-1 Started 1.7s
$ docker-compose down -v
[+] Running 4/4
⠿ Container wordpress-wordpress-1 Removed 1.5s
⠿ Container wordpress-db-1 Removed 1.9s
⠿ Volume wordpress_db Removed 0.0s
⠿ Network wordpress_wordpress Removed
재시작 후 -v를 붙이면 volume 까지 삭제되는 것을 볼 수 있음.
$ docker-compose -p my-project up --scale web=3 -d
[+] Running 4/4
⠿ Container my-project-web-3 Started 11.8s
⠿ Container my-project-web-1 Started 11.7s
⠿ Container my-project-redis-1 Running 0.0s
⠿ Container my-project-web-2 Started
웹이 3개로 증가
$ docker-compose -p my-project ps
NAME COMMAND SERVICE STATUS PORTS
my-project-redis-1 "docker-entrypoint.s…" redis running 6379/tcp
my-project-web-1 "flask run" web running 0.0.0.0:32772->5000/tcp, :::32772->5000/tcp
my-project-web-2 "flask run" web running 0.0.0.0:32771->5000/tcp, :::32771->5000/tcp
my-project-web-3 "flask run" web running 0.0.0.0:32770->5000/tcp, :::32770->5000/tcp
$ vi docker-compose.yml
version: "3.9"
services:
web:
build: .
ports:
- "5000"
redis:
image: "redis:alpine"
port binding을 할때 "5000:5000"과 같이 host port를 지정하면 scaling할 때 같은 port를 두개 이상의 container가 사용하여 충돌 발생
web 내부에 container 이름 지정이 가능한데
web:
container_name: "web"
과 같이 한다면 이 또한 충돌이 발생함.
$ docker-compose -p my-project logs
my-project-web-1 | * Serving Flask app 'app.py'
my-project-web-1 | * Debug mode: off
my-project-web-1 | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
my-project-web-1 | * Running on all addresses (0.0.0.0)
my-project-web-1 | * Running on http://127.0.0.1:5000
my-project-web-1 | * Running on http://172.19.0.5:5000
my-project-web-1 | Press CTRL+C to quit
my-project-redis-1 | 1:C 18 Apr 2023 06:51:31.970 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
my-project-redis-1 | 1:C 18 Apr 2023 06:51:31.970 # Redis version=7.0.11, bits=64, commit=00000000, modified=0, pid=1, just started
my-project-redis-1 | 1:C 18 Apr 2023 06:51:31.970 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
my-project-redis-1 | 1:M 18 Apr 2023 06:51:31.971 * monotonic clock: POSIX clock_gettime
my-project-redis-1 | 1:M 18 Apr 2023 06:51:31.972 * Running mode=standalone, port=6379.
my-project-redis-1 | 1:M 18 Apr 2023 06:51:31.972 # Server initialized
my-project-redis-1 | 1:M 18 Apr 2023 06:51:31.972 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
my-project-redis-1 | 1:M 18 Apr 2023 06:51:31.972 * Ready to accept connections
my-project-web-2 | * Serving Flask app 'app.py'
my-project-web-2 | * Debug mode: off
my-project-web-2 | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
my-project-web-2 | * Running on all addresses (0.0.0.0)
my-project-web-2 | * Running on http://127.0.0.1:5000
my-project-web-2 | * Running on http://172.19.0.4:5000
my-project-web-2 | Press CTRL+C to quit
my-project-web-3 | * Serving Flask app 'app.py'
my-project-web-3 | * Debug mode: off
my-project-web-3 | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
my-project-web-3 | * Running on all addresses (0.0.0.0)
my-project-web-3 | * Running on http://127.0.0.1:5000
my-project-web-3 | * Running on http://172.19.0.2:5000
my-project-web-3 | Press CTRL+C to quit
$ docker-compose -p my-project events
다른 bash에서 이벤트를 발생
$ docker-compose -p my-project up --scale web=1 -d
[+] Running 2/2
⠿ Container my-project-redis-1 Running 0.0s
⠿ Container my-project-web-1 Started
기존 창에서 이벤트 확인
$ docker-compose -p my-project events
2023-04-18 07:09:23.652594 container kill ca776e0195d3cd16bb04bd5b1e81263aad42940bda4e6cf19db37aefde9513b6 (image=my-project_web, signal=15, name=my-project-web-3)
2023-04-18 07:09:23.653824 container kill b9996237f22bd9b4eb3c3ceac7d8f74209f7cf59a46a93b2563d205f5f64b5f9 (image=my-project_web, name=my-project-web-1, signal=15)
2023-04-18 07:09:23.660840 container kill 976473e709debbee2734eaf5197a6eda25dbfd4c1e91c1d225da4be03031861a (signal=15, image=my-project_web, name=my-project-web-2)
2023-04-18 07:09:33.749663 container kill ca776e0195d3cd16bb04bd5b1e81263aad42940bda4e6cf19db37aefde9513b6 (signal=9, image=my-project_web, name=my-project-web-3)
2023-04-18 07:09:33.772241 container kill b9996237f22bd9b4eb3c3ceac7d8f74209f7cf59a46a93b2563d205f5f64b5f9 (name=my-project-web-1, signal=9, image=my-project_web)
2023-04-18 07:09:33.808709 container kill 976473e709debbee2734eaf5197a6eda25dbfd4c1e91c1d225da4be03031861a (name=my-project-web-2, signal=9, image=my-project_web)
2023-04-18 07:09:34.123873 container stop ca776e0195d3cd16bb04bd5b1e81263aad42940bda4e6cf19db37aefde9513b6 (image=my-project_web, name=my-project-web-3)
2023-04-18 07:09:34.127105 container die ca776e0195d3cd16bb04bd5b1e81263aad42940bda4e6cf19db37aefde9513b6 (name=my-project-web-3, exitCode=137, image=my-project_web)
2023-04-18 07:09:34.140093 container destroy ca776e0195d3cd16bb04bd5b1e81263aad42940bda4e6cf19db37aefde9513b6 (name=my-project-web-3, image=my-project_web)
2023-04-18 07:09:34.283287 container stop b9996237f22bd9b4eb3c3ceac7d8f74209f7cf59a46a93b2563d205f5f64b5f9 (name=my-project-web-1, image=my-project_web)
2023-04-18 07:09:34.288587 container die b9996237f22bd9b4eb3c3ceac7d8f74209f7cf59a46a93b2563d205f5f64b5f9 (image=my-project_web, name=my-project-web-1, exitCode=137)
2023-04-18 07:09:34.299752 container rename b9996237f22bd9b4eb3c3ceac7d8f74209f7cf59a46a93b2563d205f5f64b5f9 (oldName=/my-project-web-1, image=my-project_web, name=b9996237f22b_my-project-web-1)
2023-04-18 07:09:34.313680 container stop 976473e709debbee2734eaf5197a6eda25dbfd4c1e91c1d225da4be03031861a (image=my-project_web, name=my-project-web-2)
2023-04-18 07:09:34.318886 container die 976473e709debbee2734eaf5197a6eda25dbfd4c1e91c1d225da4be03031861a (exitCode=137, image=my-project_web, name=my-project-web-2)
2023-04-18 07:09:34.327029 container destroy 976473e709debbee2734eaf5197a6eda25dbfd4c1e91c1d225da4be03031861a (name=my-project-web-2, image=my-project_web)
2023-04-18 07:09:34.329986 container create b5a3f90f3750c4e8ad2ed7c2b68385d785a9c6c4f35e981f58971772a2cbe8a2 (image=my-project_web, name=my-project-web-1)
2023-04-18 07:09:34.345524 container destroy b9996237f22bd9b4eb3c3ceac7d8f74209f7cf59a46a93b2563d205f5f64b5f9 (image=my-project_web, name=b9996237f22b_my-project-web-1)
2023-04-18 07:09:34.713702 container start b5a3f90f3750c4e8ad2ed7c2b68385d785a9c6c4f35e981f58971772a2cbe8a2 (image=my-project_web, name=my-project-web-1)
$ docker-compose -p my-project images
Container Repository Tag Image Id Size
my-project-redis-1 redis alpine 0b405767398c 29.9MB
my-project-web-1 build_web latest a63e04828b73 215MB
$ docker-compose -p my-project ps
NAME COMMAND SERVICE STATUS PORTS
my-project-redis-1 "docker-entrypoint.s…" redis running 6379/tcp
my-project-web-1 "flask run" web running 0.0.0.0:32773->5000/tcp, :::32773->5000/tcp
$ docker-compose -p my-project top
my-project-redis-1
UID PID PPID C STIME TTY TIME CMD
lxd 6141 6099 0 06:51 ? 00:00:01 redis-server *:6379
my-project-web-1
UID PID PPID C STIME TTY TIME CMD
root 8436 8415 0 07:09 ? 00:00:00 /usr/local/bin/python /usr/local/bin/flask run
$ vi docker-compose.yml
version: '3.9'
services:
db:
image: mysql:5.7
volumes:
- db:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=wordpress
- MYSQL_DATABASE=wordpress
- MYSQL_USER=wordpress
- MYSQL_PASSWORD=wordpress
networks:
- wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
networks:
- wordpress
volumes:
db: {}
networks:
wordpress: {}
db라는 이름의 volume과 wordpress라는 이름의 network가 정의되어 있음.
network의 경우 option이 주어지지 않는 경우 bridge driver를 사용하여 network 생성
db는 값이 없는 경우 기본 docker volume을 생성
image: 이미지명:tag
volume: 볼륨: 볼륨 위치
restart: always -> container에 오류가 발생하면 재시작
environment: =, :을 사용해 지정 가능
networks: 여러 네트워크에 연결도 가능함.
depends_on: container가 실행되는 순서를 정의할 수 있음.
depends_on:
- db => wordpress 서비스는 db 서비스가 실행된 후 실행해야 함
depends_on은 해당 container가 실행되었음은 보장하나 준비되었음을 보장하지는 않음.