Jaybanuan's Blog

どうせまた調べるハメになることをメモしていくブログ

Docker Composeをsystemdのサービスにする

はじめに

サーバの簡易な運用をする場合、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 updocker-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

ExecStartPredocker-compose downを実行しているのは、ExecStartの前に念のためゴミ掃除をしておくため。 また、読み込むComposeファイルを指定するために、このユニットファイルの%iを活用してパスを作成している。 例えば、jenkinsnginxredmineの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を利用しているので、ゴミも後始末されていることが確認できる。

参考