도커 컴포즈의 이해
docker-compose, 얘는 무엇일까? 등장 배경부터 알아보자.
docker container 기술은 애플리케이션을 빠르고 경량화해서 배포하기 위해 등장했다.
우리가 쇼핑몰 애플리케이션을 만들어 컨테이너 형태로 배포한다고 생각해보자.
화면, 웹서버, WAS, DB, 모니터링, 로깅 등등 여러 기능들이 모여서 우리의 애플리케이션을 이룰것이다.
우리는 이 기능들을 컨테이너 단위로 분리하여 구성할 것이다.
컨테이너 설계는 확장성을 고려하여 stateless 하게 설계하는것이 좋고,
Utilization을 위해서라도 하나의 컨테이너안에 모든 기능(프로세스)을 넣는것은 지양해야 한다.
이때, 웹서버인 nginx에 트래픽이 몰려 쇼핑몰이 다운될 위기에 처했다면?
스케일 아웃과 스케일 업 두가지 방식에 대해 생각할 것이다.
우리는 stateless하게 컨테이너를 미리 구성해 놨기에,
nginx 컨테이너를 10개로 손쉽게 스케일 아웃할 수 있다.
슬슬 감이 온다. 만약 10개가 아니라 100개라면? 1000개라면?
이것 외에도 각 컨테이너를 run 할때 컨테이너마다 필요한 여러가지 옵션이 있다는것은 모두가 알고 있다.
docker run -d -p 80:80 --link mysql:db --name web myimage apachectl -DFOREGROUND
이들을 매번 수동으로 입력하는것은 관리하기 매우 어렵다는 단점이 있다.
도커 컴포즈는 결국에 여러 개의 컨테이너들을 한번에 문서로 관리하기 위해 등장했다.
도커 컴포즈는 미리 정의된 문서에 적힌 옵션과 환경을 읽고, 컨테이너를 순차적으로 생성한다.
도커 컴포즈의 문서 파일안에서는 docker run 명령어의 옵션을 그대로 사용할 수 있다.
도커 컴포즈 구성
위에서 말했던 도커 컴포즈가 읽는 문서는 yaml 파일로 정의할 수 있다.
yaml 파일
야믈 파일이라 읽고, yml이나 yaml이나 같은 파일이다.
옛날 윈도우 운영체제에서는 파일의 확장자가 3글자 제한이 걸려있었다.
이런 제한이 없어지고 YAML(YAML Ain't Markup Language) 라는 다소 개발자스러운 유머가 담긴 확장자가 탄생했다.
yaml은 json, xml 같이 데이터를 나타내는 포맷 형식이며 이들 중 가장 인간에게 친화적이어서 가독성이 높다.
yaml 파일은 docker-compose와 spring config, kubernetes등 여러 곳에서 쓰인다.
yaml 파일도 다룰것이 많지만 다른 포스트에서 다루겠다.
docker-compose.yaml 구성
version: "3.9" # yaml 파일 포맷의 버전을 나타낸다.
services: # 생성될 컨테이너들을 묶어놓은 단위
db: # 생성될 서비스의 이름
image: mongo # 생성될 컨테이너의 베이스 이미지
container_name: my-mongo # 생성될 컨테이너의 이름
ports:
- "27017:27017"
volumes:
- ./data/db:/data/db
nginx:
build: . # 생성될 컨테이너의 Dockerfile
ports:
- "80:80"
environment: # 생성될 컨테이너의 env
HOST: "http://localhost"
depends_on: # 컨테이너간의 의존관계를 설정
- db
도커 컴포즈는 docker-compose.yaml 파일을 읽어 컨테이너를 순차적으로 실행한다.
위의 yaml 파일을 docker run 명령어로 변환하면 다음과 같다.
docker run -d -p 27017:27017 -v ./data/db:/data/db --name my-mongo mongo
docker run -d -p 80:80 -e host=http://localhost nginx:latest
위의 yaml파일에서 특이한점은 build 부분인데,
docker-compose 에서는 실행할 컨테이너의 이미지를 build하는 Dockerfile도 지정할 수 있다.
따라서 별도의 이미지를 지정하지 않고 Dockerfile만 지정하여 컨테이너를 실행할 수 있다.
이밖에도 컨테이너들 간의 네트워크 지정, 볼륨 지정, Entrypoint 등을 명시하는 여러가지 keyword가 있으니
더 자세한 keyword 구성은 포스트 하단을 참고하면 된다.
docker-compose 명령어
도커 컴포즈는 docker-compose 명령어가 입력된 위치를 기준으로 docker-compose.yaml 파일을 찾는다.
up
docker-compose up [OPTIONS] [SERVICE...]
docker-compose up
up은 이미지 빌드, 컨테이너 생성, 컨테이너 실행을 다 포함하는 명령어이다.
위의 명령어를 실행하게 되면, 해당 명령어가 입력된 위치를 기준으로 docker-compose.yaml 파일을 찾아
개발자가 명시한 컨테이너들을 실행한다.
만약 다른 위치에 있는 yaml 파일을 타겟으로 하고 싶다면 -f 옵션을 주면 된다.
docker-compose -f ../test/docker-compose.yaml up
그리고 docker run 명령어에서 -d, detached 옵션을 주었던것처럼 docker-compose도 -d로 실행하는것이 일반적이다.
docker-compose up -d
down
docker-compose down [OPTIONS] [SERVICES]
docker-compose down
up이 있으면 down도 있다.
down이라는 어감만 보면 컨테이너를 중지시키는구나! 라고 생각하기 쉬운데
정확히는 중지시킨이후 삭제까지 진행한다.
중지만 시키는 명령어는 stop이라고 따로 존재하니 컨테이너 내부에
non-persistent한 데이터를 포함하고 있다면 조심하자.
logs
docker-compose logs [OPTIONS] [SERVICE...]
docker-compose logs -f my_container_name
docker-compose로 실행한 service의 log를 볼 수 있다.
만약 실시간으로 log를 보고 싶다면 -f 옵션을 주면 된다.
더 자세한 명령어 구성은 포스트 하단을 참고하면 된다.
docker-compose default bridge network
docker-compose up 명령어를 실행하면 다음과 같은 화면을 볼 수 있다.
도커 네트워크의 종류중에 bridge 네트워크가 있다고 이전 포스트에서 소개했었다.
하나의 docker-compose.yaml 파일에서 같이 생성된 컨테이너들은
docker-compose가 자동으로 생성해주는 bridge 네트워크에 가입 되어
서로를 서비스명으로 디스커버리할 수 있다.
test는 27017포트를 호스트에 개방한 컨테이너이므로,
ec2-user-nginx-1라는 nginx 컨테이너에 접속해서 테스트 해보자,
컨테이너 네임인 test로 해당 컨테이너를 잘 찾는것을 볼 수 있다!
docker-compose up -d의 함정
docker-compose up -d로 신나게 컨테이너를 올리다가 어느 날
분명 코드를 수정했는데 이를 빌드 후 컨테이너로 올린 다음 확인해보면
똑같은 에러를 내뿜고 있는것을 보았다.
알고보니 docker-compose로 올린 이미지가 그대로였었다.
yaml 파일에서는 이미지 대신에 Dockerfile을 명시하고 있었고
docker-compose up 명령어는 캐시를 사용해서, 해당 Dockerfile로 이미 빌드된
이미지가 존재할때는 별도의 빌드 과정을 거치지 않는다.
따라서 --build 옵션을 주어 매번 새롭게 빌드하도록 설정해 오류를 해결했다.
docker-compose up -d --build
정확한 동작 과정의 이해가 부족해서 생겼던 버그였다,,,, 조심조심!
docker-compose 명령어 레퍼런스
docker-compose 명령어에 대한 더 자세한 정보는 아래 documentation을 참고하면 된다.
https://docs.docker.com/compose/reference/
Overview of docker compose CLI
docs.docker.com
docker-compose.yaml 키워드 레퍼런스
docker-compose.yaml 키워드에 대한 더 자세한 정보는 아래 documentation을 참고하면 된다.
https://docs.docker.com/compose/compose-file/compose-file-v3/
Compose file version 3 reference
docs.docker.com
'Infra > Docker' 카테고리의 다른 글
[Docker] Docker Swarm (0) | 2023.06.28 |
---|---|
[Docker] Docker Daemon (0) | 2023.06.27 |
[Docker] Dockerfile (1) | 2023.05.20 |
[Docker] 도커 볼륨과 네트워크 (0) | 2023.05.19 |
[Docker] 도커 이미지와 컨테이너 (0) | 2023.05.18 |