Dockerfile
04_docker/04-03_web.py/docker/Dockerfile
を解説します。
行番号をふりますが、実際のファイルには左端の5バイト分(数字4桁+スペース)がありません。
行番号をふった Dockerfile 全体はこちら
コンテナのカスタマイズをしたいなら、一番重要な情報は次の2点でしょう。 よくわからないなら、 他のところはいじらないほうがよいです(いじらなくても多分なんとかなります)
Dockerfile の基礎
FROM debian
CMD echo "Helo, World!"
という短い Dockerfile を build すれば hello world コンテナになります。
hello world はともかく、
このように
Dockerfile の先頭には、元にする OS イメージの指定が来ます。
それがFROM
行で、使いたい OS イメージ名を書きます。
必要なら debian:10.10 のようにバージョン番号指定も可能です
変数による上書き
この構築ガイドで使う汎用Dockerfileでは多くの変数を外部から設定可能にしています。
build.shで解説したとおり
build.sh のオプション(–build-arg)で多くの変数の値を上書きしています。
指定している変数はIMAGE SANDBOX_UID SANDBOX_USER SANDBOX_PASSWORD SANDBOX_HOME LANG LANGUAGE TIMEZONE
です
変数は Dockerfile 全体に散らばっていますが、まずは0001-0016行が最初の設定部分になります。
0001-0002 行では利用する OS イメージを指定します。
0001 ARG IMAGE
0002 FROM ${IMAGE}
コマンドラインで –build-arg IMAGE=debian:10.11 オプションをつけているので、 これらの行は
FROM debian:10.11
の意味に解釈されます。
ちなみに –build-arg で使う変数は、
Dockerfile の中でARG 変数名
という形で宣言されている必要があります。
そのため、0002行目の FROM 以前に 0001 行目の ARG IMAGE 宣言が必要です
0004-0013 では同じくコマンドラインオプションで指定する変数 LANG LANGUAGE TIMEZONE の値を上書きしています。 これらは –build-arg オプションの使用例として入れてありますが、 この構築においては、そんなに重要ではありません。 でも、変な警告とか出たりするのもイヤなので、 言語やタイムゾーンは適切に設定しておきましょう
0004 # fundamental: language, timezone
0005 ARG LANG
0006 ARG LANGUAGE
0007 ARG TIMEZONE
0008 ENV LANG=${LANG}
0009 ENV LC_CTYPE=${LANG}
0010 ENV LC_MESSAGES=${LANG}
0011 ENV LC_ALL=
0012 ENV LANGUAGE=${LANGUAGE}
0013 ENV TZ=${TIMEZONE}
0015-0016 行目はオマケです、このガイドでは利用していない設定です(が、消し忘れていた:-) 無視してください
0019-0039 行目で必要なソフトウエアをインストールしています。以下、コメントは適当に省略していきます。
0019 ENV DEBIAN_FRONTEND noninteractive
0019 行は、パッケージ管理ソフトが[y/n]
と聞いてこなくてよいとパッケージ管理システムに伝える設定です
0029 ARG PKG_BASE="locales tzdata sudo procps"
0030 ARG PKG_UTILTIES
0031 ARG PKG_MODEL_SPECIFIC="systemd coreutils python3 python3-pip telnet curl"
ここ(0029-0031行)で PKG_BASE PKG_UTILITIES PKG_MODEL_SPECIFIC という変数を定義し、
インストールしたいパッケージ群をカテゴリごとに定義しています。
変数は${変数}
と書けば展開されます(下を参照)。
コンテナにパッケージを追加したいのなら、 PKG_MODEL_SPECIFIC を編集して curl の右側に入れたいパッケージ名を追加していけばよいでしょう
0033-0039 は長い一行のコマンドを\
で複数行に書いています。
なお、パッケージを追加するだけなら 0033-0039 行目を改変する必要はありません
(上に書いたようにPKG_MODEL_SPECIFIC変数に追加するだけでよい)。
0033 RUN apt-get update && \
0034 apt-get install -y ${PKG_BASE} \
0035 ${PKG_MODEL_SPECIFIC} \
0036 ${PKG_UTILTIES} && \
0037 apt-get -y autoremove && \
0038 apt-get clean && \
0039 rm -rf /var/lib/apt/lists/*
意味は… とりあえず最低限の解説はしておきましょう
- RUN 「文字列」は「文字列」部分を実行せよと docker build に伝える命令文です
- 「文字列」の部分はシェルの構文です
コマンドA && コマンドB
は「コマンドAが成功すればコマンドBを実行する」という意味です- 折り返しをといて、
一行にすれば
RUN コマンドA && コマンドB && コマンドC && コマンドD && コマンドE
なので、 5つすべてが成功するなら、コマンドA〜コマンドEまでが順番に実行されていきます
- aptなんとかはdebianのパッケージ管理システムのコマンド
- 変数は
${変数}
と書くと展開されるので、0034-0036行はapt-get install -y locales tzdata sudo ... curl
のように解釈されます
ようするに、 シェルプログラミングの基礎つまり Unix のコマンドライン操作がわからないと理解できません。 Unix操作法がわからないと、クラウドもどうにもならないことが噛みしめられましたね? :-)
後半戦ではコンテナのカスタマイズ
おそらく 0041-0047に手を入れる必要はありません。変更する必要があるとすれば 0050 行以降です
0041 RUN sed -i "/${LANG}/s/^# //" /etc/locale.gen && locale-gen && update-locale LANG=${LANG}
0041行は念のためコマンドでロケール(言語設定)を再設定しています。 なんかaptにまかせておくとうまくいかないことがあるためです
0043-0046は変数SANDBOX_ほげほげの宣言と初期値の設定をしています。 docker build のコマンドラインオプションで上書きされない場合、この初期値が使われます
0043 ARG SANDBOX_UID=1000
0044 ARG SANDBOX_USER=docker
0045 ARG SANDBOX_PASSWORD=docker
0046 ARG SANDBOX_HOME=/home/$SANDBOX_USER}
0047 行もシェル構文の実行です。ここではコンテナのデフォルトユーザ${SANDBOX_USER}
を作成しています
0047 RUN [ $SANDBOX_UID -ne 0 ] && { useradd -m --uid ${SANDBOX_UID} --groups sudo,video --shell /bin/bash ${SANDBOX_USER} && echo ${SANDBOX_USER}:${SANDBOX_PASSWORD} | chpasswd; } || true
0050 行もシェル構文の実行です。 pip3 (Python 3自身のパッケージ管理システムのコマンド)で、 www.py が必要としている mysql ライブラリ(mysql-connector-python)をインストールします。
0050 RUN /usr/bin/pip3 install mysql-connector-python
必要な Python ライブラリがあれば、ここに追加してください
0056-0058 は、
- 0056: コンテナ内に /sandbox ディレクトリを作成し、
- 0057: docker build を実行しているディレクトリにある ./files ディレクトリをコンテナ内の /sandbox へコピーします
0056 RUN mkdir /sandbox
0057 COPY files /sandbox
0058 RUN find /sandbox -type d -name CVS | xargs rm -fr || true
0058 はゴミを消して(クリーニングして)いるだけです
最後です。 コンテナ実行環境をデフォルトユーザへ切り替えます。
- 0060: ディレクトリを
${SANDBOX_HOME}
へ変更 - 0061: ねんのため
${SANDBOX_HOME}
のpermission(権限)を${SANDBOX_USER}
へ設定 - 0062: コンテナで処理を実行するデフォルトユーザを
${SANDBOX_USER}
へ設定
0060 WORKDIR ${SANDBOX_HOME}
0061 RUN chown -R ${SANDBOX_USER} ./
0062 USER ${SANDBOX_USER}
最後の最後に実行するものをENTRYPOINTと呼んでいます。
0064 ENTRYPOINT ["/sandbox/entrypoint.sh"]
コンテナの起動時、
コンテナ内の/sandbox/entrypoint.sh
というスクリプトを実行するとコンテナをしつけています。
なお、entrypoint.shは終わらない処理である必要があります