Docker Compose 란?

Docker Compose 란 여러 개의 컨테이너들을 관리, 실행하기 위한 "툴" 로, 각각 독립된 컨테이너의 실행을 정의합니다.

Docker Compose 는 왜 필요한가?

도커 컨테이너끼리 연결을 편하게 하기 위해서

github 에서 express 서버 구성 코드를 pull 받고, 이를 컨테이너화하기 위해 다음과 같이 build 할 수 있습니다.

$ docker build -t express-demo .

이제 express-demo 컨테이너를 실행하고, DB로 mysql 컨테이너를 실행해보겠습니다.

express-demo 컨테이너 실행

$ docker run --name express -d -p 8080:8080 express-demo

mysql 컨테이너 실행

$ docker run -d --name mysqlDb -e MYSQL_DB=mysqlSample -e MYSQL_USER=demouser -e MYSQL_PASSWORD=demosecret mysql

express-demo 컨테이너와 demo 컨테이너가 실행되었지만, express-demo에서 DB를 찾지 못하고 있기 때문에 에러가 발생하는 걸 볼 수 있습니다.

이럴 때는, 먼저 DB를 컨테이너화한 뒤, express-demo 를 컨테이너화시킬 때 --link 옵션으로 연결해줄 수 있습니다.

mysql 컨테이너 실행

$ docker run -d --name mysqlDb -e MYSQL_DB=mysqlSample -e MYSQL_USER=demouser -e MYSQL_PASSWORD=demosecret mysql

express-demo 컨테이너 실행 및 --link 옵션으로 mysql 컨테이너와 연결

$ docker run --name express -d -p 8080:8080 -e MYSQL_DB_HOST=db --link mysql:db express-demo

express-demo를 run할 때, -e 옵션으로 db를 지정해주고 --link 옵션으로 연결해주었기 때문에 서버가 잘 실행될 수 있습니다.

하지만, 만약 여러 컨테이너가 더 있다고 하면 매번 이렇게 실행시키는 것이 불편하고 연결하는 중 문제가 발생할 수 있습니다.

특정 컨테이너만 공유하는 가상 네트워크를 편리하게 연결하기 위해서

위와 동일한 방법으로 express-demo 컨테이너를 하나 더 띄우면, MySQL DB에 연결됩니다. 이는 다른 컨테이너들이 모두 접근할 수 있다는 걸 의미하며 보안의 취약점입니다.

docker 는 가상 네트워크를 지원하기 때문에 이런 보안 취약점을 관리할 수 있습니다.

현재 가상 네트워크를 확인하는 명령어는 아래와 같습니다.

$ docker network ls

가상 네트워크를 생성하는 명령어는 아래와 같습니다.

$ docker network create --driver bridge [가상 네트워크 이름 입력]

이제 다시 mysql 을 먼저 컨테이너화 시킵니다. --network 옵션으로 가상 네트워크 이름을 추가할 수 있습니다.

$ docker run -d --name mysql --network webservice -e MYSQL_DB=expressdemo -e MYSQL_USER=demouser -e MYSQL_PASSWORD=demosecret mysql

express-demo를 연결할 때도 가상 네트워크 이름을 붙여 컨테이너를 실행합니다.

$ docker run -d --name express-demo --network webservice -p 8080:8080 -e MYSQL_DB_HOST=db --link mysql:db mysql-demo

이후 --network 옵션이 지정되지 않은 컨테이너는 해당 mysql 에 연결되지 못하고 아래와 같은 Error 를 반환합니다.

docker: Error response from daemon: Cannot link to /mysql, as it does not belog to the default network.

실행 명령어를 일일이 입력하기 번거로워서

nginx 컨테이너를 실행하기 위해서는 아래와 같은 명령어를 입력해야 합니다.

$ docker run -it nginx

하지만, nginx 의 특성상 port 를 지정해 주지 않으면 존재하는 의미가 없습니다. 그래서 -p 옵션을 지정해 컨테이너를 실행해야 합니다.

$ docker run -it -p 8080:80 nginx

docker stop [container ID] 명령어를 실행해 컨테이너를 종료시켰을 때, docker ps -a 명령어를 실행하면 컨테이너가 종료된 채로 남아있는 것을 볼 수 있습니다.

--rm 옵션을 지정하면 컨테이너 종료 시 자동으로 삭제되도록 할 수 있습니다.

$ docker run -it -p 8080:80 --rm nginx

컨테이너를 종료했다가 다시 실행시켰을 때, 이전 데이터를 그대로 사용하고 싶다면 -v 옵션을 지정해주면 됩니다.

$ docker run -it -p 8080:80 --rm -v $(pwd):/usr/share/nginx/html/nginx

이렇게 옵션이 추가될 때마다 명령어가 계속해서 늘어나기 때문에 이를 문서로 관리해야 할 필요성을 느낄 것입니다.

 

명령어를 짧고 간결하게 사용하기 위해 부수적인 옵션들을 파일로 관리할 수 있게 해주는 것이 docker-compose 의 역할 중 하나입니다.

docker-compose는 yml 파일에 이런 설정을 모두 담아 간단한 명령어로 docker 를 실행시킬 수 있게 해줍니다.

복사했습니다!