Compose는 다중 컨테이너 Docker 애플리케이션을 정의
하고 실행
하기 위한 도구
YAML 파일
을 사용하여 애플리케이션 서비스를 구성
단일 명령을 사용하여 구성에서 모든 서비스를 생성하고 시작합니다.
아래의 일련의 작업들을 반복적으로 할 필요없이 문서로 관리할 수 있게 해주는 것이 docker-compose 입니다.
docker-compse는 yml 파일에 실행에 관련된 설정을 모두 담음으로써, 간단한 명령으로 docker를 실행시킬 수 있습니다.
# docker-compose.yml
version: '3'
volumes:
postgres_data: {}
services:
db:
image: postgres
volumes:
- postgres_data:/var/lib/postgres/dat
environment:
- POSTGRES_DB=djangosample
- POSTGRES_USER=sampleuser
- POSTGRES_PASSWORD=samplesecret
django:
build:
context: .
dockerfile: ./compose/django/Dockerfile-dev
volumes:
- ./:/app/
command: ["./manage.py", "runserver", "0:8000"]
environment:
- DJANGO_DB_HOST=db
depends_on:
- db
restart: always
ports:
- 8000:8000
yml 파일을 통해 아래와 같이 docker 컨테이너를 간단히 실행하고 종료시킬 수 있습니다.
$ docker-compose up -d
$ docker-compose down
nginx 컨테이너를 실행하기 위해서는 아래와 같은 명령할 수 있다.
$ docker run -it nginx
하지만, ngix의 특성상 port를 지정하지 않으면 아무짝에도 쓸모가 없다. 그래서 아래처럼 컨테이너를 실행한다.
$ docker run -it -p 8080:80 nginx
컨테이너를 종료시켰을 때, docker ps -a 명령을 치면 컨테이너가 종료된채로 남아있는것을 볼 수 있다. 종료되면 자동으로 삭제되게 하려면 아래와 같이 --rm 옵션을 붙인다.
$ docker run -it -p 8080:80 --rm nginx
컨테이너를 종료했다가 다시 실행시켰을 때, 유지될 수 있게 volumn mount를 하고 싶다면 -v옵션을 사용한다.
$ docker run -it -p 8080:80 --rm -v $(pwd):/usr/share/nginx/html/ nginx
이렇게 옵션이 추가될 때 마다 명령어가 계속해서 늘어나기 때문에 이를 문서로 관리하고 싶어진다.
이렇듯 명령을 짧고 간결하게 사용
하기 위해서 부수적인 옵션들을 파일로 관리
할 수 있게해주는 것이 docker-compose의 역할 중 하나이다.
docker-compose [docker-compose.yml 위치] up --build -d;
위 명령어를 한 번 실행하면, 각 컨테이너를 위한 이미지를 생성하는 dockerfile 을 실행하고 컨테이너를 생성하고, 3 개의 프로그램을 연결까지 해준다.
만약, docker-compose가 없다면
docker network create [network 이름]
docker run -d --name [container 이름] --network [network 이름] [이미지 이름]
여기서는 네트워크에 연결하는 코드를 3번 입력해야한다.
docker-compose 를 사용하지 않으면, 더 많은 커맨드를 입력해야하는 번거로움이 생긴다.
github에서 django 소스를 내려받고, 이를 컨테이너 시키기 위해 아래처럼 build 할 수 있습니다.
$ docker build -t django-sample .
이제 django 컨테이너를 실행하고, DB로 postgres 컨테이너를 실행해보도록 하죠.
$ docker run --rm -d --name django -p 8000:8000 django-sample
$ docker run --rm -d --name postgres -e POSTGRES_DB=djangosample -e POSTGRES_USER=sampleuser -e POSTGRES_PASSWORD=samplesecret postgres
django 컨테이너와 postgres 컨테이너가 실행되었지만, djang에서 DB를 못찾고 있기 때문에 에러가 발생하는걸 볼 수 있습니다.
이럴땐, 먼저 DB를 컨테이너 시킨 뒤, django를 컨테이너화시킬 때 --link 옵션으로 연결해줄 수 있습니다.
$ docker run --rm -d --name postgres -e POSTGRES_DB=djangosample -e POSTGRES_USER=sampleuser -e POSTGRES_PASSWORD=samplesecret postgres
$ docker run -d --rm -p 8000:8000 -e DJANGO_DB_HOST=db --link postgres:db django-sample
django를 run할 때, -e 옵션으로 db를 지정해주고 --link 옵션으로 연결해주었기 때문에 서버가 잘 실행될 수 있습니다. 하지만, 더 여러 컨테이너가 있다고하면 매번 이렇게 run시키는 것이 불편하고 연결이 문제가 발생합니다.
위에 방법으로 django 컨테이너를 하나 더 띄우면, postgres DB에 연결됩니다. 이는 다른 컨테이너들이 모두 접근할 수 있다는 의미이고 보안의 취약점입니다.
docker는 가상 네트워크를 지원하기 때문에 이런 보안 취약점을 관리할 수 있습니다.
아래 명령어를 입력하면 현재 가상 네트워크를 확인할 수 있습니다.
$ docker network ls
가상 네트워크를 생성하는 명령어는 아래와 같습니다.
$ docker network create --driver bridge [가상 네트워크 이름 입력]
이제 다시 postgres를 먼저 컨테이너화 시킵니다. --network 옵션으로 가상 네트워크 이름이 추가됩니다.
$ docker run --rm -d --name postgres --network web-service -e POSTGRES_DB=djangosample -e POSTGRES_USER=sampleuser -e POSTGRES_PASSWORD=samplesecret postgres
django를 연결할 때도 가상 네트워크 이름을 붙여 run을 합니다.
$ docker run -d --rm --name django1 --network web-service -p 8000:8000 -e DJANGO_DB_HOST=db --link postgres:db django-sample
이후 --network 옵션이 지정되지 않은 컨테이너는 해당 postgres에 연결되지 못하고 Error를 반환합니다.
docker: Error response from daemon: Cannot link to /postgres, as it does not belong to the default network.
참고
https://velog.io/@jewon119/TIL112.-Docker-Docker-compose%EB%A5%BC-%EC%93%B0%EB%8A%94-%EC%9D%B4%EC%9C%A0
https://velog.io/@jaekim/Docker-compose