[CentOS7]dockerコンテナの起動・停止をsystemd Service UNITで制御する

dockerコンテナの起動や停止をsystemd Service UNITで制御する為の設定を行います。
この設定をおこなうことにより、systemctlコマンドでコンテナの起動や停止、自動起動の設定が行えるようになります。

この設定でできるようになること

docker-compose.ymlで定義されたdockerコンテナ群を以下のsystemctlコマンドで起動・停止できるようになります。
また、同様にsystemctlコマンドで自動起動設定やjournalctlコマンドでログが確認できます。

# 起動
$ sudo systemctl start compose@redmine.service
# 停止
$ sudo systemctl stop compose@redmine.service
# 自動起動
$ sudo systemctl enable compose@redmine.service
# ログ
$ sudo journalctl -f -u compose@redmine.service

systemd service UNIT化するメリット

自動起動するコンテナの管理

dockerコンテナは、docker-compose.ymlに

restart: always

と記述することにより、OS起動時に自動起動するようにすることができますが、これだとホスト上に多数のdocker-compose.ymlがある場合、
起動管理がむずかしくなります。

unless-stopped

“restart: unless-stopped”もありますが、ホストを複数人で管理している場合、なかなか管理が難しくなります。

docker-compose.yml配置場所の統一

複数人でサーバを管理する場合、配置する場所をきめておくとこは重要です。
docker-compose.ymlの配置場所もばらばらだと同じように管理が難しいので今回の設定でdocker-compose.ymlの配置場所を決まった場所に
配置するルールをつくることによりサーバの管理が楽になります。

決め事

service UNITの単位はdocker-compose.yml単位

systemd service UNITで起動するコンテナの単位は docker-compose.yml単位とします。

以降、この単位を「プロジェクト」と呼びます。

docker-compose.ymlの配置場所

docker-compose.ymlの配置場所は以下のルールに従い配置するものとします。

/opt
  +-- compose
         +-- compose.d
               +-- プロジェクト
                       +-- docker-compose.yml
               +-- プロジェクト
                       +-- docker-compose.yml
               +-- プロジェクト
                       +-- docker-compose.yml

このルールに従い、systemd service UNITファイルの実装を行います。

service UNITのプロセスオーナ

service UNITのプロセスオーナは一般ユーザとします。
本稿では「compose」ユーザとします。

環境

以下の環境を前提とします

  • CentOS7
  • docker-ce 18.06.0.ce-3.el7
  • docker-compose version 1.12.0

上記環境の構築はこちら→  [CentOS7]docker-ceとdocker-composeの導入 – Zero Configuration

では実際の構築を行います。

service UNITのプロセスオーナ作成

service UNITのプロセスオーナである「compose」ユーザを作成します
作成するユーザはグループ「docker」に所属させ、dockerコマンドがsudoなしで扱えるようにします

$ sudo useradd -g docker -s /sbin/nologin -M compose

service UNITの作成

docker-composeを使い、dockerコンテナを起動・停止する systemd service UNITファイルを作成します。
service UNITファイルのテンプレート機能を使い、任意のdocker-composeファイルを制御できるようにします。

作成するファイルは「/etc/systemd/system/compose@.service」です。
“@”がテンプレート機能です。
@以降に指定した文字を定義ファイル内に置き換えてくれます。
この機能を使い、決められた場所にあるdocker-compose.ymlを指すようにservice UNITファイルを作成します。

最初に、systemd service UNITらしく、/etc/sysconfig/に環境設定ファイルを準備します

$ sudo vi /etc/sysconfig/compose

ファイルの内容は以下です。

#プロジェクトルートパス
COMPOSED_HOME=/opt/compose/compose.d

また、プロジェクト毎に独自の環境設定ができるようにする為のディレクトリを準備します。

$ sudo mkdir -p /etc/sysconfig/compose.d

つづいて、service UNITファイルを作成します。

$ sudo vi /etc/systemd/system/compose@.service

ファイルの内容は以下です。

[Unit]
Description=docker-compose %i service
Requires=docker.service
After=docker.service
[Service]
User=compose
Type=simple
EnvironmentFile=-/etc/sysconfig/compose
EnvironmentFile=-/etc/sysconfig/compose.d/%i
Environment=COMPOSE_FILE=%i/docker-compose.yml
ExecStartPre=-/usr/local/bin/docker-compose -f ${COMPOSED_HOME}/${COMPOSE_FILE} kill
ExecStartPre=-/usr/local/bin/docker-compose -f ${COMPOSED_HOME}/${COMPOSE_FILE} rm -v -f
ExecStartPre=-/usr/local/bin/docker-compose -f ${COMPOSED_HOME}/${COMPOSE_FILE} down
ExecStart=-/usr/local/bin/docker-compose -f ${COMPOSED_HOME}/${COMPOSE_FILE} up --force-recreate --abort-on-container-exit
ExecStop=-/usr/local/bin/docker-compose -f ${COMPOSED_HOME}/${COMPOSE_FILE} stop
ExecStopPost=-/usr/local/bin/docker-compose -f ${COMPOSED_HOME}/${COMPOSE_FILE} rm -v -f
ExecStopPost=-/usr/local/bin/docker-compose -f ${COMPOSED_HOME}/${COMPOSE_FILE} down
Restart=always
RestartSec=180s
[Install]
# Run Level = 2,3,4
WantedBy=multi-user.target

この設定により、例えば

$ sudo systemctl start compose@redmine.service

と実行すると、

/opt/compose/compose.d/redmine/docker-compose.ymlを使ったコンテナが実行されます。

プロジェクトディレクトリの作成

冒頭で決めた場所にdocker-compose.ymlを配置する場所を作成します

$ sudo mkdir -p /opt/compose/compose.d

プロジェクトの作成と実行

例として、プロジェクト名をredmineとした、docker-compose.ymlを作成します。

#プロジェクトディレクトリの作成
$ sudo mkdir -p /opt/compose/compose.d/redmine
# docker-compose.ymlの作成
$ sudo vi /opt/compose/compose.d/redmine/docker-compose.yml

あとは、systemctlコマンドを使って実行するだけです

# 実行
$ sudo systemctl start compose@redmine.service
# 停止
$ sudo systemctl stop compose@redmine.service
# 自動起動
$ sudo systemctl enable compose@redmine.service

同じように、別のプロジェクトも作成・実行

/opt
  +-- compose
         +-- compose.d
               +-- redmine
                       +-- docker-compose.yml
               +-- redmine2
                       +-- docker-compose.yml
               +-- redmine3
                       +-- docker-compose.yml
# 実行
$ sudo systemctl start compose@redmine2.service
$ sudo systemctl start compose@redmine3.service

最後に

dockerコンテナをsystemd service UNITで起動制御することにより、コンテナの起動管理がしやすくなります。

ぜひお試しください。