위 포스팅을 진행하면서 django이미지와 mariadb이미지를 따로따로 만들어서 구동시키는 작업을 했다.
하지만 컨테이너가 많아진다면 이미지를 하나씩 만들어야 하고, 컨테이너를 하나씩 구동시킬 때마다 볼륨과 네트워크 환경변수 등을 새로 설정해줘야 한다.
이 작업들을 연속해서 터미널로 하다 보면 한 두 개씩 빠트리는 변수가 생길 수 있기 때문에 docker 개발자들은 docker-compose.yml이라는 파일에 컨테이너를 구동하기 위한 정보들을 모아놓을 수 있는 방법을 개발해주었다.!
docker-compose를 사용해서 개발환경을 구성해보자
지난번에 git clone을 했다면 다시 할 필요가 없다.
지금까지 만들었던 django 이미지와 django 컨테이너, mariadb 컨테이너를 삭제하자.
$ docker rm {django 컨테이너 이름, mariadb 컨테이너 이름}
$ docker rmi {django 이미지 이름}
docker-compose의 특징
여러 프로젝트를 격리시켜 관리할 수 있다.
프로젝트 이름은 기본적으로 compose를 실행한 폴더명이 기준이 되며 별도로 지정이 가능하다.
$ docker-compose -p test1 up
$ docker-compose -p docker1 up
-p 명령어를 사용해서 별도의 프로젝트 이름을 정할 수 있다.
compose파일 내의 컨테이너 명과 합쳐진다면 {프로젝트 이름_컨테이너명}과 같은 방식으로 컨테이너가 만들어진다.
기본적으로 Docker Compose는 하나의 디폴트 네트워크에 모든 컨테이너를 연결한다. 디폴트 네트워크의 이름은 프로젝트의 이름 뒤에 _default가 붙는다. 네트워크를 따로 설정해 준다면 디폴트 네트워크는 무시된다.
변경된 컨테이너만 재생성
도커는 컨테이너를 만드는 데 사용되는 구성을 캐시로 저장하기 때문에 변경되지 않은 이미지를 가지고 컨테이너 생성을 시도하면, compose는 기존 컨테이너를 다시 사용한다.
루트 디렉토리를 보면 docker-compose.yml파일이 있을 것이다. 내용을 자세히 살펴보자.
docker-compose.yml
version: "3.8"
services:
mariadbtest:
image: mariadb:10.5
networks:
- docker
ports:
- 3306:3306
volumes:
- ${PWD}/database:/var/lib/mysql
environment:
MARIADB_ROOT_PASSWORD: 1234
MARIADB_DATABASE: django
djangotest:
build:
context: .
dockerfile: ./localbind.Dockerfile
networks:
- docker
ports:
- 8000:8000
volumes:
- ${PWD}:/home/Docker_Practice
depends_on:
- mariadbtest
networks:
docker:
version: "3.8"
docker-compose.yml 파일의 첫 줄에는 파일 규격 버전을 적는다.
파일의 규격에 따라 지원하는 옵션이 달라지는데, “3”이라만 적으면 3으로 시작하는 최신 버전을 사용한다는 의미이다. (파일 규격 버전에 따른 자세한 내용은 공식 문서를 참고하자.)
services:
service는 사실 나중에 포스팅할 docker stack과 관련이 깊다.
docker-compose는 yml파일에 작성된 컨테이너들을 정의해서 구동하는 것이기 때문에 compose를 통해서 service 내부에 있는 컨테이너들을 정의하고 만든다고 생각하면 된다.
mariadbtest:
생성하려고 하는 컨테이너의 이름이다. 도커의 네트워크 내부에서 컨테이너 자체가 host명으로 사용될 수 있다는 점을 기억하자.
image: mariadb:10.5
현재 만들어져 있는 mariadb:10.5 이미지를 사용해서 컨테이너를 만들겠다는 뜻이다.
networks:
- docker
만들 컨테이너를 'docker' 네트워크에 포함시킨다는 뜻이다.
ports:
- 3306:3306
host의 3306 포트와 컨테이너의 3306 포트를 연결시킨다는 뜻이다.
이때 오른쪽의 3306 포트는 컨테이너가 오픈하는 포트(Dockerfile의 EXPOSE)로, 충돌에 대한 위험이 거의 없다.
하지만 왼쪽의 3306 포트는 host 와 연결되는 포트이므로 호스트에서 3306을 따로 사용하고 있다면 다른 포트로 변경해주자.
volumes:
- ${PWD}/database:/var/lib/mysql
host의 특정 디렉터리와 컨테이너 내부의 /var/lib/mysql을 bind볼륨으로 연결시켜 준다는 뜻이다.
environment:
MARIADB_ROOT_PASSWORD: 1234
MARIADB_DATABASE: django
컨테이너의 환경변수를 설정해준다.
djangotest:
build:
context: .
dockerfile: ./localbind.Dockerfile
djangotest라는 컨테이너를 만들고 이미지는 빌드해서 사용한다는 뜻이다.
이미지의 위치는 context : . 이므로 현재 디렉터리의 Dockerfile을 사용한다는 뜻이다.
dockerfile을 지정해주는데 현재 디렉터리의 localbind.Dockerfile을 사용해서 이미지를 빌드한다.
depends_on:
- mariadbtest
볼륨, 네트워크, 포트는 위와 동일하므로 생략했다.
depends_on은 mariadbtest 컨테이너가 구동되고 현재 컨테이너를 구동해야 한다는 뜻이다.
django 컨테이너는 db부분에 mariadb가 연결되지 않은 상태에서 구동시킨다면 migrate를 할 때 db가 연결되지 않아 반드시 오류가 발생한다. 따라서 mariadbtest 컨테이너에 대한 의존성을 부여해 주는 역할이다.
** depends_on 옵션은 단지 컨테이너간의 시작 순서만 결정해 준다. mariadb 컨테이너가 완전히 구동된 이후에 다른 컨테이너를 실행시키고 싶다면 임의의 스크립트 파일을 실행시켜 확인하는 작업이 필요하다.
networks:
docker:
compose에 기본적으로 사용될 network를 지정해 주는 역할이다.
networks 이외에도 특정 named 볼륨을 사용하거나 docker secret을 사용하면 따로 적어주어야 한다.
docker-compose 실행
현재 실습에 필요한 docker-compose.yml의 구성요소를 살펴보았다.
$ docker-compose up -d
위 명령어를 실행해서 컨테이너를 한 번에 만들고 실행해 보자.
처음엔 djangotest이미지를 만들어야 해서 시간이 조금 걸릴 수도 있다.
터미널에서 컨테이너를 run 명령어를 사용해서 하나씩 만들 때마다 훨씬 편해진 걸 느낄 수 있을 것이다.
특히 연결할 볼륨이나 환경변수들이 많을 경우 터미널로 하나하나 쳐서 컨테이너를 만들기는 너무 어려울 것이다. 컨테이너에 대한 명세가 될뿐더러 실수할 위험도 적기 때문에 docker-compose.yml을 만들어서 사용하는 걸 추천한다!
'DevOps > Docker' 카테고리의 다른 글
[Docker] Docker Swarm 서비스하기 (0) | 2021.08.24 |
---|---|
[Docker] Docker Swarm에 대해서 (0) | 2021.08.18 |
[Docker] Docker 관련 tip #1 (0) | 2021.08.10 |
[Docker] Django 개발 환경 세팅 #2 (0) | 2021.08.05 |
[Docker] Django 개발 환경 세팅 #1 (0) | 2021.08.04 |