Dockerコンテナでsystemdを使う

結論

Dockerイメージにsystemdが含まれている場合は単にそれをエントリーポイントとして指定する。
含まれていない場合はシェルスクリプトをエントリーポイントにすれば強引に解決できる。

バージョン

前提

Dockerコンテナで複数のプロセスを走らせるのは良しとされないことが多いようだ。
とはいうものの、商用環境はコンテナでないのにローカル開発環境はコンテナで、ローカルでも商用環境と同じようなサーバー構成にしたい場合など、
コンテナをVMのように使いたいケースもある。

そのようなケースでは(商用環境同様に)systemdを使ってサービス等を管理したくなるが、
それをどのように行うか。

やり方

systemdが正常に動作するためにはそれが最初のプロセスとして、即ちPID 1で起動している必要がある。

Dockerイメージにsystemdが含まれていれば、ENTRYPOINT: /usr/sbin/initとすればよい。
しかし、含まれていない場合(例えばamazonlinux:2.0.20190508)にはどうすべきか。

当初はENTRYPOINT: /bin/bash等としてdocker runし、systemdをインストール後にエントリーポイントを変更すれば良いのではないかと考えた。
しかし、エントリーポイントは後からは変更できないようだ。

結局以下のようなシェルスクリプトを書き、これをエントリーポイントに渡すことにした。
強引ではあるが、元々思想的に微妙なことをしているのでやむなし。

#!/bin/bash

ls /usr/sbin/init > /dev/null 2>&1
INIT_BIN_EXISTS=$?

if [ "${INIT_BIN_EXISTS}" == 0 ]; then
  exec /usr/sbin/init
else
  /bin/bash
fi