[![logo](https://www.hongsnet.net/images/logo.gif)](https://www.hongsnet.net)

# Docker compose로 컨테이너 관리/제어

> 명령어 Based의 컨테이너를 실행해보고, **docker-compose**로 관리하는 과정을 알아본다.

# 개요

컨테이너를 가끔 생성하는 경우는 상관없겠지만, **컨테이너의 생성빈도가 높고**, **실행 시켜야하는 컨테이너가 지금보다 더 늘어난다면** 상당히 번거로운 작업이 될 것이다. 즉, 여러 개의 컨테이너를 한 번에 실행시키고 관리할 수 있다면 효율적일 것이다. **docker-compose**는 여러 컨테이너를 한 번에 관리할 때 아주 유용하다. **YAML**(확장자 : **.yml**) 파일을 이용하여 어떠한 이미지를 사용하여, 어떤 컨테이너를 실행시킬 것이지를 기술해주면 Docker는 해당 내용대로 컨테이너를 순차적으로 실행시켜준다.


# Docker Demo URL

> https://swarm.freehongs.net/


# 컨테이너의 실행

다음은 내부 Repository의 Apache2.4 + PHP7.4가 연동되어있는 이미지를 이용해서 컨테이너를 생성하는 명령이다.

```bash
# docker run -d --name hongsnet-php74 \
> -v  /DOCKERS/var_www_html:/var/www/html \
> -p 9800:80 \
> registry.hongsnet.net/joohan.hong/docker/php:centos7-httpd-php74
Unable to find image 'registry.hongsnet.net/joohan.hong/docker/php:centos7-httpd-php74' locally
centos7-httpd-php74: Pulling from joohan.hong/docker/php
Digest: sha256:e94e7d5e152c2b4c3c0d6ab94f4cda5c1f7e589e548a3d2d7dba6e10a33dd803
Status: Downloaded newer image for registry.hongsnet.net/joohan.hong/docker/php:centos7-httpd-php74
5926d0afe820400d5e7974ce33a71fdc7c22a1c7ab68f2c9f0e14bf30d041d05
```

> 실행은 **docker run** 명령으로 수행한다. 만약 다수의 컨테이너를 실행해야한다면, 위의 명령이 더 길어질 것이다.

- **컨테이너 확인**

```bash
# docker ps
CONTAINER ID   IMAGE                                                              COMMAND                  CREATED          STATUS          PORTS                  NAMES
5926d0afe820   registry.hongsnet.net/joohan.hong/docker/php:centos7-httpd-php74   "/usr/bin/supervisor…"   2 minutes ago    Up 2 minutes    0.0.0.0:9800->80/tcp   hongsnet-php74
```

- **컨테이너 중지**

```bash
# docker stop hongsnet-php74
hongsnet-php74
```

컨테이너를 `제거`하려면, 아래와 같이 명령 한다.

```bash
# docker rm hongsnet-php74
hongsnet-php74
```

만약 다음과 같이 Swarm 환경에서 Replica 등의 다른 설정이 포함되어야 한다면, 명령어가 좀 더 복잡해질 것이다. 따라서 관리 측면에서 **docker-compose**를 이용하면 관리가 수월해진다.


# Docker compose를 이용한 관리

## docker-compose 설치

```bash
# curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
```

## docker-compose 기본

- **시작**

```bash
# docker-compose up <- 포그라운드 실행

# docker-compose up -d <- 백그라운드 실행
```

- **중지 또는 제거**

```bash
# docker-compose stop <- 중지

# docker-compose rm <- 제거
```

- **컨테이너 확인**

```bash
# docker-compose ps
           Name                         Command               State          Ports
------------------------------------------------------------------------------------------
httpd-php_hongsnet-php74_1   /usr/bin/supervisord -c /e ...   Up      0.0.0.0:9800->80/tcp
```

## docker-compose YAML 파일 작성

위의 Apache2.4 + PHP7.4 컨테이너를 실행하기 위해 다음과 같이 .yml 파일에 기술하면 된다.

```bash
# cat docker-compose.yml
version: '3'

services:
  hongsnet-php74:
   image: registry.hongsnet.net/joohan.hong/docker/php:centos7-httpd-php74
   ports:
     - 9800:80
   volumes:
     - "/DOCKERS/var_www_html:/var/www/html"
```

컨테이너 실행은 다음과 같이 수행한다.

```bash
# docker-compose up -d
Creating network "httpd-php_default" with the default driver
Creating httpd-php_hongsnet-php74_1 ... done
```

그럼 위의 **DEMO Url**에서 운용되는 컨테이너를 다음과 같이 docker-compose로 배포한다.

```bash
# cat docker-stack.yml
version: '3'

services:
  hongsnet-php74:
   image: registry.hongsnet.net/joohan.hong/docker/php:centos7-httpd-php74
   ports:
     - 9800:80
   volumes:
     - "/DOCKERS/var_www_html:/var/www/html"
   deploy:
     mode: replicated
     replicas: 5
     update_config:
       parallelism: 5
       delay: 10s
     restart_policy:
       condition: on-failure
       max_attempts: 3
       window: 120s
```

```bash
# docker stack deploy --with-registry-auth --compose-file=docker-stack.yml php
Creating network php_default
Creating service php_hongsnet-php74
```

그럼 다음과 같이 5개의 Replica가 운용되는 Swarm 기반의 서비스가 운용된다.

```bash
# docker service ls
ID             NAME                    MODE         REPLICAS   IMAGE                                                              PORTS
shhi42vq59fi   php_hongsnet-php74      replicated   5/5        registry.hongsnet.net/joohan.hong/docker/php:centos7-httpd-php74   *:9800->80/tcp
```

# Extras

위의 https://swarm.freehongs.net Demo URL은 Apache Reverse Proxy 시스템이며, 설정은 다음과 같다.

```bash
# cat swarm.conf
<VirtualHost *:80>
    ServerName swarm.freehongs.net
    Redirect permanent / https://swarm.freehongs.net/
</VirtualHost>

<VirtualHost *:443>
        ServerName swarm.freehongs.net
        ServerAdmin master@hongsnet.net

        ProxyRequests Off
        SSLProxyEngine On

        ProxyPreserveHost On
        AllowEncodedSlashes NoDecode

        <Proxy *>
                Order deny,allow
                Allow from All
        </Proxy>

        SSLEngine on
        SSLProxyVerify none

        SSLCertificateFile /etc/letsencrypt/live/freehongs.net/cert.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/freehongs.net/privkey.pem
        SSLCertificateChainFile /etc/letsencrypt/live/freehongs.net/chain.pem
        SSLCACertificateFile /etc/letsencrypt/live/freehongs.net/fullchain.pem

        # 아래 내용 추가
        <Proxy "balancer://mycluster">
                BalancerMember "http://172.24.0.238:9800" #Manager01
                BalancerMember "http://172.24.0.239:9800" #Manager02
                BalancerMember "http://172.16.0.235:9800" #Manager03
                BalancerMember "http://172.16.0.236:9800" #Node01
        </Proxy>

        # 아래 내용 추가
        ProxyPass               "/"     "balancer://mycluster/"
        ProxyPassReverse        "/"     "balancer://mycluster/"

        #RequestHeader set X-Forwarded-Proto "https"
        #RequestHeader set X-Forwarded-Port "443"
</VirtualHost>

```

Swarm Cluster의 구성현황은 다음과 같다.

```bash
# docker node ls
ID                            HOSTNAME               STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
2smb95jog1melt4ok0ptpn3n9 *   TB2-DOCKER-MANAGER01   Ready     Active         Reachable        20.10.2
libu6alzhci724h31ji3z6fb7     TB2-DOCKER-MANAGER02   Ready     Active         Leader           20.10.2
2jy4lkwokf20w9gfe9cyqb3w7     TB3-DOCKER-MANAGER03   Ready     Active         Reachable        20.10.2
3h6eeb8p5f1fcwes0a8dpotzr     TB3-DOCKER-NODE01      Ready     Active                          20.10.2
```

