はじめに
サーバの簡易な運用をする場合、Docker Composeを利用してコンテナを立ち上げると簡単に環境を構築できる。 さらにDocker Composeをsystemdのサービスにすることで、起動や停止などのライフサイクルも管理できる。
ここでは、コンテナを利用した簡易なサーバ運用のために、Docker Composeをsystemdのサービスにする方法をメモしておく。
環境
$ cat /etc/os-release | grep PRETTY_NAME PRETTY_NAME="Ubuntu 18.04.4 LTS" $ docker --version Docker version 19.03.5, build 633a0ea838 $ docker-compose --version docker-compose version 1.25.4, build 8d51620a
ユニットファイルの作成
基本的には、どのようなコンテナを利用する場合もdocker-compose up
とdocker-compose down
を実行するだけなので、ユニットファイルのテンプレート化が可能である。
ここでは、次に示すテンプレート化したユニットファイル/etc/systemd/system/docker-compose-service@.service
を作成する。
[Unit] Description=%i managed by docker-compose Requires=docker.service [Service] Type=simple Environment=COMPOSE_FILE=/opt/docker-compose-service/%i/docker-compose.yml ExecStartPre=-/usr/local/bin/docker-compose -f ${COMPOSE_FILE} down --volumes ExecStart=/usr/local/bin/docker-compose -f ${COMPOSE_FILE} up ExecStop=/usr/local/bin/docker-compose -f ${COMPOSE_FILE} down --volumes [Install] WantedBy=multi-user.target
ExecStartPre
でdocker-compose down
を実行しているのは、ExecStart
の前に念のためゴミ掃除をしておくため。
また、読み込むComposeファイルを指定するために、このユニットファイルの%i
を活用してパスを作成している。
例えば、jenkins
とnginx
とredmine
の3つのサービスを運用する場合は、次のようなファイル構成になる。
/opt `-- docker-compose-service |-- jenkins | `-- docker-compose.yml |-- nginx | `-- docker-compose.yml `-- redmine `-- docker-compose.yml
Composeファイルの準備とサービスの登録
ここでは例として、ポート10080でHTTPを受け付けるNginxのサービスを登録する。
まずは、以下の内容でComposeファイル/opt/docker-compose-service/nginx/docker-compose.yml
を作成する。
これは、ポート番号10080でアクセス可能なNginxを実行するだけのComposeファイルである。
version: '3.7' services: nginx: image: nginx:1.17 ports: - 10080:80
サービスとして登録するには、以下の以下のコマンドを実行する。
$ sudo systemctl enable --now docker-compose-service@nginx
動作確認
まずはsystemdからステータスを確認してみる。
$ systemctl status docker-compose-service@nginx ● docker-compose-service@nginx.service - nginx managed by docker-compose Loaded: loaded (/etc/systemd/system/docker-compose-service@.service; indirect; vendor preset: enabled) Active: active (running) since Tue 2020-02-11 13:11:38 JST; 57min ago Process: 715 ExecStartPre=/usr/local/bin/docker-compose -f ${COMPOSE_FILE} down --volumes (code=exited, status=0/SUCCESS) Main PID: 2018 (docker-compose) Tasks: 4 (limit: 4637) CGroup: /system.slice/system-docker\x2dcompose\x2dservice.slice/docker-compose-service@nginx.service ├─2018 /usr/local/bin/docker-compose -f /opt/docker-compose-service/nginx/docker-compose.yml up └─2063 /usr/local/bin/docker-compose -f /opt/docker-compose-service/nginx/docker-compose.yml up 2月 11 13:11:27 ubuntu1804 systemd[1]: Starting nginx managed by docker-compose... 2月 11 13:11:37 ubuntu1804 docker-compose[715]: Removing nginx_nginx_1 ... 2月 11 13:11:37 ubuntu1804 docker-compose[715]: [75B blob data] 2月 11 13:11:38 ubuntu1804 systemd[1]: Started nginx managed by docker-compose. 2月 11 13:11:39 ubuntu1804 docker-compose[2018]: Creating network "nginx_default" with the default driver 2月 11 13:11:40 ubuntu1804 docker-compose[2018]: Creating nginx_nginx_1 ...
Nginxのコンテナがdocker-compose
経由で正常に立ち上がっていることが分かる。
docker
コマンドからも確認してみる。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b4f4c0a9b306 nginx:1.17 "nginx -g 'daemon of…" 57 minutes ago Up 57 minutes 0.0.0.0:10080->80/tcp nginx_nginx_1
docker
コマンドの結果からも、Ningxのコンテナが起動していることが確認できる。
では、curl
でNginxにアクセスしてみる。
$ curl http://localhost:10080/ <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> (以下略)
正常にNginxにアクセスできたことが分かる。 最後に、サービスを停止してみる。
$ sudo systemctl stop docker-compose-service@nginx
systemdからステータスを確認してみる。
$ systemctl status docker-compose-service@nginx ● docker-compose-service@nginx.service - nginx managed by docker-compose Loaded: loaded (/etc/systemd/system/docker-compose-service@.service; indirect; vendor preset: enabled) Active: inactive (dead) since Tue 2020-02-11 14:16:05 JST; 23s ago Process: 14572 ExecStop=/usr/local/bin/docker-compose -f ${COMPOSE_FILE} down --volumes (code=exited, status=0/SUCCESS) Process: 2018 ExecStart=/usr/local/bin/docker-compose -f ${COMPOSE_FILE} up (code=exited, status=0/SUCCESS) Process: 715 ExecStartPre=/usr/local/bin/docker-compose -f ${COMPOSE_FILE} down --volumes (code=exited, status=0/SUCCESS) Main PID: 2018 (code=exited, status=0/SUCCESS) 2月 11 13:11:40 ubuntu1804 docker-compose[2018]: Creating nginx_nginx_1 ... 2月 11 14:07:24 ubuntu1804 docker-compose[2018]: [71B blob data] 2月 11 14:07:24 ubuntu1804 docker-compose[2018]: nginx_1 | 172.18.0.1 - - [11/Feb/2020:05:07:24 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.58.0" "-" 2月 11 14:16:02 ubuntu1804 systemd[1]: Stopping nginx managed by docker-compose... 2月 11 14:16:03 ubuntu1804 docker-compose[14572]: Stopping nginx_nginx_1 ... 2月 11 14:16:05 ubuntu1804 docker-compose[2018]: nginx_nginx_1 exited with code 0 2月 11 14:16:05 ubuntu1804 docker-compose[14572]: [71B blob data] 2月 11 14:16:05 ubuntu1804 docker-compose[14572]: [75B blob data] 2月 11 14:16:05 ubuntu1804 docker-compose[2018]: 2月 11 14:16:05 ubuntu1804 systemd[1]: Stopped nginx managed by docker-compose.
正常にサービスが停止したことが分かる。
docker
コマンドからも確認してみる。
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
docker
コマンドの結果より、起動しているコンテナがないことが分かる。
また、systemdの停止のコマンドとしてdocker-compose down
を利用しているので、ゴミも後始末されていることが確認できる。
参考
Docker Compose
man sytstemd.service
man systemd.unit