こちらは起動時の環境変数(PUID、PGUID)で実行ユーザーを変更できる
-e PGID for GroupID - see below for explanation
-e PUID for UserID - see below for explanation
このような実装をする場合、/etc/passwd
に存在しない UID などが指定された時どうするかがよく問題となるが、このイメージは起動時にそのユーザーを作成している。以下にその仕組について調べた内容を記述する。
linuxserver/docker-mysql
の Dockerfile を確認する。
この Dockerfile では、 CMD
が存在しないので FROM
で指定された linuxserver/baseimage
の設定が使われる。
linuxserver/baseimage
の Dockerfile では、CMD ["/sbin/my_init"]
となっている。
しかし、この Dockerfile 内では /sbin/my_init
が追加されていないのでどのようなものかがわからない。
そこで、FROM
で指定されている phusion/baseimage:0.9.18
を追いかけてみる。
phusion/baseimage:0.9.18
の Dockerfile を確認すると、以下のようにセットアップが全て外部のスクリプトで行われている。
https://github.com/phusion/baseimage-docker/blob/rel-0.9.18/image/Dockerfile#L4-L9
ADD . /bd_build
RUN /bd_build/prepare.sh && \
/bd_build/system_services.sh && \
/bd_build/utilities.sh && \
/bd_build/cleanup.sh
この中の system_services.sh 内にて /sbin/my_init
の配置がされている。
この /sbin/my_init
の内容は baseimage-docker/image/bin/my_init で確認できるが、これはいわゆる init として機能する Python製のスクリプトだ。
今回必要な特徴としては run_startup_files()
の中で /etc/my_init.d
の中や sysvinit と同じように /etc/rc.local
を処理していてる。
ただし、このイメージ内では /etc/my_init.d
以下へのファイルの追加は行っていない。
また、メインの処理として runit の実行を行っている。
これにより、/service
以下が runit の管理でデーモンのように実行されるようになっている。
そこで、一つ前の linuxserver/baseimage
の Dockerfile から確認すると、ユーザー作成スクリプト が /etc/my_init.d
に追加されていることがわかる。
このスクリプトの中で環境変数(PUID、GUID)を元に abc というユーザーが作成されている。
更に戻って、linuxserver/docker-mysql
の Dockerfile で追加されている /service
の run を確認すると以下のようになっている。
#!/bin/bash
/sbin/setuser abc /usr/bin/mysqld_safe --skip-syslog
/sbin/setuser
というのは phusion/baseimage:0.9.18
で追加されているこれまた Python 製スクリプトで引数で指定されたユーザーでコマンドを実行するスクリプトである。
これらから、起動時に指定された PUID/GUID で abc ユーザー作成を行いその abc ユーザーで mysql を実行するという形になる。
しょうがないとは言え、なかなか面倒なことになっていてわかりにくいので私は好きではない。決め打ちでユーザー作ってしまう方が正直楽。 気になる点としては、起動後に別ユーザーに switch するたぐいのアプリケーションをどうするか等がある。 ただ、現状は一番汎用性が高い方法ではないかなと思う。