September 4, 2019

Docker-Compose 다중 컨테이너 관리하기

[Docker-Compose information]

Docker-Compose는 여러 컨테이너를 모아 관리할 수 있는 유용한 도구입니다.

또한, Docker-Compose는 Dockerfile처럼 "docker-compose.yml" 파일에 컨테이너의 구체적인 정보와 "Dockerefile"를 함께 사용하여 호스트 상 여러 컨테이너를 한 번에 관리할 수 있습니다.

제일 큰 강점은 "Compose"를 통해 개발 환경을 어디에서든지 동일하게 환경을 구성할 수 있습니다.

"docker-compose" 명령을 실행하여 여러 개의 컨테이너를 한 번에 실행하거나 정지를 할 수 있으며, 컨테이너 구성정보를 YAML 형식(.yml 확장자)으로 관리할 수 있습니다.




[Docker-Compose install]

dongdonge@dongdonge$ sudo apt-get install docker-compose -y


dongdonge@dongdonge$ docker-compose version
docker-compose version 1.17.1, build unknown


dongdonge@dongdonge$ docker version
Client:
 Version:           18.09.7
 API version:       1.39
 Go version:        go1.10.1
 Git commit:        2d0083d
 Built:             Fri Aug 16 14:20:06 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.09.7
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.1
  Git commit:       2d0083d
  Built:            Wed Aug 14 19:41:23 2019
  OS/Arch:          linux/amd64
  Experimental:     false

Docker-Compose를 사용하기 위해 설치를 진행하였습니다. 현재 Docker "18.09.7" 버전 / Compose "1.17.1" 설치된 걸 확인할 수 있습니다.





[Docker-Compose docker-compose.yml 작성하기]

"docker-compose.yml"를 작성하기전 아래와 같이 구성하였습니다.

.
├── docker-compose.yml
├── mysql
│   └── Dockerfile
└── web
    ├── Dockerfile
    └── index.php

현재 디렉터리 구성


메인에 존재하는 "docker-compose.yml"로 컨테이너 및 이미지를 관리하고, 하위 디렉터리별 "mysql/Dockerfile"와 "web/Dockerfile"을 통해 컨테이너에 필요한 이미지를 제작합니다.




# Docker container Apache:php + Mysql Server
version: '3'

services:
  apache_web:
    restart: always
    container_name: Apache_Webs
    build:
          context: /docker-compose - TEST/web/
          dockerfile: /docker-compose - TEST/web/Dockerfile
    ports:
      - "1234:80"
    depends_on:
      - mysql_db
    links:
      - mysql_db:mysql_db
    
      
  mysql_db:
    restart: always
    container_name: Mysql_DBS
    build:
          context: /docker-compose - TEST/mysql/
          dockerfile: /docker-compose - TEST/mysql/Dockerfile

docker-compose.yml


우선 작동 원리와 컨테이너 관리를 먼저 파악한 뒤 다음에 명령에 대해 설명하도록 하겠습니다.

위 "docker-compose.yml" 파일은 웹서버 컨테이너와 디비서버 컨테이너를 간단하게 분리시켜 생성한 뒤, 링크로 연결되어 있습니다.




FROM mysql:5.7

ENV MYSQL_ROOT_PASSWORD="toor"
ENV MYSQL_DATABASE "DongDongE"
ENV MYSQL_USER "DongDongE"
ENV MYSQL_PASSWORD "toor"

EXPOSE 3306 
CMD ["mysqld"]

mysql/Dockerfile




FROM php:7.3-apache

COPY index.php /var/www/html/

EXPOSE 80
CMD apachectl -D FOREGROUND

web/Dockerfile




<?php phpinfo(); ?>

web/index.php





[Docker-Compose Container Start]

"Docker-Compose"를 통해 Container를 시작해보겠습니다.

dongdonge@dongdonge$ docker-compose up -d

Creating network "dockercomposetest_default" with the default driver
Building mysql_db
Step 1/7 : FROM mysql:5.7
5.7: Pulling from library/mysql
9fc222b64b0a: Pulling fs layer
291e388076f0: Pulling fs layer
9fc222b64b0a: Downloading [>                                                  ]  228.5kB/22.52MB290b: Downloading [=============>                                     ]  1.191MB
9fc222b64b0a: Downloading [==>                                                ]  1.146MB/22.52MB290b: Downloading [=================>                                 ]  1.584MB
291e388076f0: Downloading [=============>                                     ]     486B
291e388076f0: Downloading [==================================================>]  1.748kB
9fc222b64b0a: Downloading [=====>                                             ]  2.297MB
.....
Status: Downloaded newer image for mysql:5.7
 ---> e1e1680ac726
Step 2/7 : ENV MYSQL_ROOT_PASSWORD="toor"
 ---> Running in c46616c30f2a
Removing intermediate container c46616c30f2a
 ---> 26f990bbf1f9
Step 3/7 : ENV MYSQL_DATABASE "DongDongE"
 ---> Running in 3a1c045e91dd
Removing intermediate container 3a1c045e91dd
 ---> 311814510bdd
Step 4/7 : ENV MYSQL_USER "DongDongE"
 ---> Running in b657a33a4f6c
Removing intermediate container b657a33a4f6c
 ---> 264ec484dc50
Step 5/7 : ENV MYSQL_PASSWORD "toor"
 ---> Running in 7ef5f73c721a
Removing intermediate container 7ef5f73c721a
 ---> 76378a7ef977
Step 6/7 : EXPOSE 3306
 ---> Running in c76d57e2adf7
Removing intermediate container c76d57e2adf7
 ---> 725305713879
Step 7/7 : CMD ["mysqld"]
 ---> Running in 3ee1b5b8ea34
Removing intermediate container 3ee1b5b8ea34
 ---> 5e50567cd525
Successfully built 5e50567cd525
Successfully tagged dockercomposetest_mysql_db:latest
.....
Building apache_web
Step 1/4 : FROM php:7.3-apache
7.3-apache: Pulling from library/php
1ab2bdfe9778: Pull complete
1448c64389e0: Pull complete
4b8a4e62b444: Pull complete
9eb9d1e8e241: Pull complete
d20b2d19292c: Pull complete
023060ea5930: Pull complete
a7fa99bc84ac: Pull complete
084397ea0b0b: Pull complete
27f2e3242e8a: Pull complete
c53d955b925a: Pull complete
55a8a68dea39: Pull complete
b78786d44570: Pull complete
69dd7e866b60: Pull complete
2907cf87b0bb: Pull complete
Digest: sha256:3314ed226566124b5a863b31c05b6f098f2dacad8ad52c40d53f08dc1ddce014
Status: Downloaded newer image for php:7.3-apache
 ---> aa4bdc74350b
Step 2/4 : COPY index.php /var/www/html/
 ---> 38239ab3143c
Step 3/4 : EXPOSE 80
 ---> Running in 9bde9dcbd906
Removing intermediate container 9bde9dcbd906
 ---> cb20ed5ccaed
Step 4/4 : CMD apachectl -D FOREGROUND
 ---> Running in a1991c3fa70a
Removing intermediate container a1991c3fa70a
 ---> 832e5697b1fe
Successfully built 832e5697b1fe
Successfully tagged dockercomposetest_apache_web:latest
WARNING: Image for service apache_web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating dockercomposetest_mysql_db_1 ... 
Creating dockercomposetest_mysql_db_1 ... done
Creating dockercomposetest_apache_web_1 ... 
Creating dockercomposetest_apache_web_1 ... done

docker-compose up


"docker-compose up -d" 명령을 통해 컨테이너를 실행합니다.




dongdonge@dongdonge$ docker images

REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
dockercomposetest_apache_web   latest              832e5697b1fe        3 minutes ago       414MB
dockercomposetest_mysql_db     latest              5e50567cd525        3 minutes ago       373MB
php                            7.3-apache          aa4bdc74350b        27 hours ago        414MB
mysql                          5.7                 e1e1680ac726        3 weeks ago         373MB

docker image list


현재 도커 이미지 리스트를 조회 시 도커 컨테이너의 기반이 되는 베이스 이미지 "php:7.3-apache"와 "mysql:5.7"를 먼저 다운로드를 받습니다.

"dockercomposetest_apache_web"와 "dockercomposetest_mysql_db" 방금 제작한 컨테이너의 이미지가 생성되었습니다.




dongdonge@dongdonge$ docker ps -a

CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                  NAMES
b2432e474cf7        dockercomposetest_apache_web   "docker-php-entrypoi…"   6 minutes ago       Up 6 minutes        0.0.0.0:1234->80/tcp   dockercomposetest_apache_web_1
eb077d17bfca        dockercomposetest_mysql_db     "docker-entrypoint.s…"   6 minutes ago       Up 6 minutes        3306/tcp, 33060/tcp    dockercomposetest_mysql_db_1

작동중인 컨테이너


"Docker-Compose"로 생성한 컨테이너가 정상적으로 구동되고 있습니다. 확인을 하기 위해 도커 웹서버 페이지를 불러오도록 하겠습니다.




[Docker Container Web Server]





[Docker-Compose docker-compose.yml 옵션 설명 ]

아래 내용은 Docker-Compose.yml 옵션에 대한 설명입니다.

  • versions: '3'

정의 파일에 대한 버전을 작성합니다. 버전에 따라 사용할 수 있는 명령이 제한되어 있습니다.

Compose Version Docker Version
3.7 18.06.0+
3.6 18.02.0+
3.5 17.12.0+
3.4 17.09.0+
3.3 17.06.0+
3.2 17.04.0+
3.1 1.13.1+
3.0 1.13.0+
2.4 17.12.0+

Version 표



  • image: mysql:5.7

Docker Container의 베이스 이미지를 지정할 때 사용합니다.
만약 BASE IMAGE를 "Dockerfile" 통하여 작업을 진행한다면 사용하지 않습니다.

현재 "mysql의 5.7"를 베이스 이미지를 기반으로 컨테이너를 제작하였습니다.
또한 로컬 호스트 환경에 베이스 이미지가 존재하지 않는다면 도커 허브를 통해 다운로드를 받고, 이미 존재한다면 다운로드 받지 않고 그대로 이미지를 사용하며, 컨테이너를 생성합니다.

생성된 컨테이너를 따로 베이스 이미지로 생성하지 않습니다.



  • build:

        context: /docker-compose - TEST/web/

        dockerfile: /docker-compose - TEST/web/Dockerfile

"context"를 이용하여 Dockerfile의 디렉터리 경로를 작성합니다.

"dockerfile" 경우는 절대/상대 경로를 통하여 작성할 수 있으며 dockerfile의 이름 및 확장자가 기본이 아닌 사용자 명으로 변경할 경우 쓰여야 합니다.



  • ports:

        - "1234:80"

"context"를 이용하여 호스트에 포트를 공개할 수 있습니다. (외부 접근 허용)

호스트포트 대신 컨테이너 포트만 작성하였을 경우 랜덤값으로 지정됩니다. 또한 "ports" 대신 "expose"를 사용하여 외부접근을 불가능하고 컨테이너끼리 또는 호스트에서 컨테이너로 포트 연결할 때 사용됩니다.

Ex) ports: "호스트 포트:컨테이너 포트"
Ex) expose: "1234"



  • depends_on:

        - mysql_db

"depends_on"를 사용하여 종속성 순서대로 도커 컨테이너 서비스를 시작할 수 있습니다.
현재 "depends_on: mysql_db" 옵션이 있으므로, 웹서버보단 "mysql_db" 컨테이너가 먼저 시작됩니다.



  • command: sh /root/backup.sh

  • entrypoint:

        - sh

        - /root/backup.sh

"command"와 "entrypoint"를 이용하여 Docker Container가 실행될 때 명령어가 실행됩니다.

둘의 차이점은 "entrypoint"는 override 할 수 있습니다.



        - mysql_db:mysql_db

"links"는 다른 컨테이너와 연결할 때 사용합니다. 서비스명과 함께 앨리어스명(별칭)을 붙일 수 있습니다.

현재 "mysql_db" 서비스와 연결하였으며, 별칭 또한 "mysql_db"로 설정되었습니다.

Ex) "links: - 서비스명: 별칭"



  • container_name: Apache_Webs

"container_name"를 사용하여 해당 컨테이너가 생성될 때 컨테이너명을 지정할 수 있습니다.

Ex) container_name: 컨테이너명





[Docker-Compose 실행 명령어 ]

아래 내용은 Docker-Compose 실행 명령어입니다.

Docker Compose로 다중 컨테이너를 관리하고 정의 및 실행할 수 있습니다.

dongdonge@dongdonge$ sudo docker-compose help

Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name (default: directory name)
  --verbose                   구체적으로 출력 표시
  --no-ansi                   Do not print ANSI control characters
  -v, --version               버전 출력
  -H, --host HOST             데몬 소켓에 연결

  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the name specified
                              in the client certificate (for example if your docker host
                              is an IP address)
  --project-directory PATH    Specify an alternate working directory
                              (default: the path of the Compose file)

Commands:
  build              서비스 빌드
  bundle             Generate a Docker bundle from the Compose file
  config             Validate and view the Compose file
  create             Create services
  down               컨테이너, 네트웤, 이미지, 볼륨 중지 및 제거 진행
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             이미지 리스트 출력
  kill               컨테이너 강제 종료
  logs               컨테이너 로그 출력
  pause              컨테이너 일시 정지
  port               컨테이너 포트 바인딩 공개 포트 출력
  ps                 컨테이너 목록 출력
  pull               Pull service images
  push               Push service images
  restart            컨테이너 재시작
  rm                 컨테이너 삭제
  run                컨테이너 실행
  scale              Set number of containers for a service
  start              컨테이너 시작
  stop               컨테이너 중단
  top                컨테이너 별로 실행중인 프로세스 출력
  unpause            Unpause services
  up                 컨테이너 생성 및 시작
  version            Show the Docker-Compose version information




[Docker-Compose up 명령어 ]

Docker-Compose "up" 명령어는 다중 이미지 및 컨테이너를 생성하고 시작할 수 있습니다.

참고로 docker-compose는 현재 경로의 "docker-compose.yml" 바탕으로 작동됩니다.


docker-compose up <옵션> <--scale SERVICE=갯수> <서비스..>

아래 옵션을 통해 확인해보도록 하겠습니다.

dongdonge@dongdonge$ sudo docker-compose up --help

Builds, (re)creates, starts, and attaches to containers for a service.

Unless they are already running, this command also starts any linked services.

The `docker-compose up` command aggregates the output of each container. When
the command exits, all containers are stopped. Running `docker-compose up -d`
starts the containers in the background and leaves them running.

If there are existing containers for a service, and the service's configuration
or image was changed after the container's creation, `docker-compose up` picks
up the changes by stopping and recreating the containers (preserving mounted
volumes). To prevent Compose from picking up changes, use the `--no-recreate`
flag.

If you want to force Compose to stop and recreate all containers, use the
`--force-recreate` flag.

Usage: up [options] [--scale SERVICE=NUM...] [SERVICE...]

Options:
    -d                         백그라운드에서 컨테이너 실행
                               Incompatible with --abort-on-container-exit.
    --no-color                 흑백으로 출력
    --no-deps                  Don't start linked services.
    --force-recreate           Recreate containers even if their configuration
                               and image haven't changed.
                               Incompatible with --no-recreate.
    --no-recreate              If containers already exist, don't recreate them.
                               Incompatible with --force-recreate.
    --no-build                 이미지 빌드를 하지 않는다.
    --no-start                 Don't start the services after creating them.
    --build                    컨테이너 시작전 이미지 빌드
    --abort-on-container-exit  Stops all containers if any container was stopped.
                               Incompatible with -d.
    -t, --timeout TIMEOUT      Use this timeout in seconds for container shutdown
                               when attached or when containers are already
                               running. (default: 10)
    --remove-orphans           Remove containers for services not
                               defined in the Compose file
    --exit-code-from SERVICE   Return the exit code of the selected service container.
                               Implies --abort-on-container-exit.
    --scale SERVICE=NUM        Scale SERVICE to NUM instances. Overrides the `scale`
                               setting in the Compose file if present****




아래 명령어는 다중 이미지/컨테이너를 빌드후 백그라운드로 실행합니다.

dongdonge@dongdonge$ docker-compose up -d
Creating network "dockercomposetest_default" with the default driver
Building mysql_db
Step 1/7 : FROM mysql:5.7
 ---> 383867b75fd2
Step 2/7 : ENV MYSQL_ROOT_PASSWORD="toor"
 ---> Running in a22329caec81
Removing intermediate container a22329caec81
 ---> 4f951609d2dd
Step 3/7 : ENV MYSQL_DATABASE "DongDongE"
 ---> Running in bcf7e0110214
Removing intermediate container bcf7e0110214
 ---> 1c207463ff08
Step 4/7 : ENV MYSQL_USER "DongDongE"
 ---> Running in f7b4457c24ed
Removing intermediate container f7b4457c24ed
 ---> c70dd6ede338
Step 5/7 : ENV MYSQL_PASSWORD "toor"
 ---> Running in adbc99a06d01
Removing intermediate container adbc99a06d01
 ---> e52841b7501b
Step 6/7 : EXPOSE 3306
 ---> Running in 12234afe44e6
Removing intermediate container 12234afe44e6
 ---> 9e65c1c5a47d
Step 7/7 : CMD ["mysqld"]
 ---> Running in 919bb99a344a
Removing intermediate container 919bb99a344a
 ---> d7869e4109ee
Successfully built d7869e4109ee
Successfully tagged dockercomposetest_mysql_db:latest
WARNING: Image for service mysql_db was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Building apache_web
Step 1/4 : FROM php:7.3-apache
 ---> 41c1d7e4012d
Step 2/4 : COPY index.php /var/www/html/
 ---> 471c43c35ac0
Step 3/4 : EXPOSE 80
 ---> Running in 5ab94e2993a9
Removing intermediate container 5ab94e2993a9
 ---> 559f633cc0dd
Step 4/4 : CMD apachectl -D FOREGROUND
 ---> Running in 66cb18c69c8f
Removing intermediate container 66cb18c69c8f
 ---> 95061875a2e0
Successfully built 95061875a2e0
Successfully tagged dockercomposetest_apache_web:latest
WARNING: Image for service apache_web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating Mysql_DBS ... 
Creating Mysql_DBS ... done
Creating Apache_Webs ... 
Creating Apache_Webs ... done




[Docker-Compose ps 명령어 ]

Docker Compose에서 생성된 컨테이너 목록을 표시 합니다.

dongdonge@dongdonge$ sudo docker-compose ps
   Name                  Command               State                 Ports              
----------------------------------------------------------------------------------------
Apache_Webs   docker-php-entrypoint /bin ...   Up      80/tcp                           
Mysql_DBS     docker-entrypoint.sh mysqld      Up      0.0.0.0:1235->3306/tcp, 33060/tcp




[Docker-Compose start/stop/restart 명령어 ]

Docker Compose에서 생성된 컨테이너를 시작/중단/재시작할 때 사용합니다.

dongdonge@dongdonge$ docker-compose start
Starting mysql_db   ... done
Starting apache_web ... done

dongdonge@dongdonge$ docker-compose stop
Stopping Apache_Webs ... done
Stopping Mysql_DBS   ... done

dongdonge@dongdonge$ docker-compose restart
Restarting Apache_Webs ... done
Restarting Mysql_DBS   ... done