📌 이 포스팅에서는 Docker-compose를 쓰는 이유에 대해 정리하였습니다.
🔥 실행 명령어를 일일이 입력하기 복잡해서
🔥 컨테이너끼리 연결을 편하게 하기 위해서
🔥 가상 네트워크를 편리하게 연결하기 위해서
🔥 docker-compose의 장점
✔️ 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의 역할 중 하나이다.
✔️ 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.
✔️ 위 처럼 django와 postgres만 연결하는데 여러 명령어 뿐 아니라 여러가지 옵션이 사용됩니다. bridge도 만들어줘야합니다.
# postgres run
docker run --rm -d --name postgres \
--network web-service \
-e POSTGRES_DB=djangosample \
-e POSTGRES_USER=sampleuser \
-e POSTGRES_PASSWORD=samplesecret \
postgres
# django1 run
docker run -d --rm --name django1 \
--network web-service \
-p 8000:8000 \
-e DJANGO_DB_HOST=db \
--link postgres:db \
django-sample
# django2 run
docker run -d --rm --name django2 \
--network web-service \
-p 8001:8000 \
-e DJANGO_DB_HOST=db \
--link postgres:db \
django-sample
✔️ 이러한 작업을 반복적으로 할 필요없이 문서로 관리할 수 있게 해주는 것이 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