DevOps/Docker

[Docker] docker-compose로 편하게 개발환경 구성하기

Henu 2021. 8. 10. 16:52
 

[Docker] Django 개발 환경 세팅 #1

[Docker] MariaDB - docker로 관리하기 [Docker] Nginx 웹서버 구동해보기 컨테이너에 대하여 [Container 시리즈] 00. Container/ Docker란 뭔가요? Container / Docker 컨테이너.. 들어봤는데 무엇인지 잘 모르겠..

hyeo-noo.tistory.com

 

 

[Docker] Django 개발 환경 세팅 #2

[Docker] Django개발 환경 세팅 #1 [Docker] MariaDB - docker로 관리하기 [Docker] Nginx 웹서버 구동해보기 컨테이너에 대하여 [Container 시리즈] 00. Container/ Docker란 뭔가요? Container / Docker 컨테이..

hyeo-noo.tistory.com

 

위 포스팅을 진행하면서 django이미지와 mariadb이미지를 따로따로 만들어서 구동시키는 작업을 했다.

하지만 컨테이너가 많아진다면 이미지를 하나씩 만들어야 하고, 컨테이너를 하나씩 구동시킬 때마다 볼륨과 네트워크 환경변수 등을 새로 설정해줘야 한다.

이 작업들을 연속해서 터미널로 하다 보면 한 두 개씩 빠트리는 변수가 생길 수 있기 때문에 docker 개발자들은 docker-compose.yml이라는 파일에 컨테이너를 구동하기 위한 정보들을 모아놓을 수 있는 방법을 개발해주었다.!

 

docker-compose를 사용해서 개발환경을 구성해보자


 

GitHub - hyun98/Docker_Practice: Django-Nginx 서버를 Docker를 통해 로컬에서 구동해보는 연습코드

Django-Nginx 서버를 Docker를 통해 로컬에서 구동해보는 연습코드. Contribute to hyun98/Docker_Practice development by creating an account on GitHub.

github.com

지난번에 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을 만들어서 사용하는 걸 추천한다!