Chapter 13

3部: イメージのビルド

ほげさん
ほげさん
2022.03.21に更新

【 2部: イメージの基礎 】で学んだことを実践して、3コンテナ分のイメージを用意します。

全体構成とハイライト

image

やることの確認

やること できるようになること
App 👉 イメージをビルド PHP が準備できる
メール送信が準備できる
App コンテナを起動しビルド結果を確認
Web サーバを起動
Dockerfile の妥当性が確認できる
Web サーバが起動できる
App ソースコードをバインドマウント ホストマシンの .php 編集が即反映される
App コンテナのポートを公開 ブラウザからアクセスできる
App コンテナをネットワークに接続
データベースサーバの接続設定
メールサーバの接続設定
DB コンテナに接続できる
Mail コンテナに接続できる
App Docker Compose 化 これらを1コマンドで再現できる
DB 👉 イメージをビルド 文字コードとログの設定ができる
DB 環境変数を指定してコンテナを起動 Dockerfile の妥当性が確認できる
MySQL サーバが起動できる
ユーザとデータベースを作成できる
DB データ置場にボリュームをマウント テーブルがコンテナ削除で消えなくなる
DB 初期化クエリをバインドマウント コンテナ起動時にテーブルが作成される
DB コンテナをネットワークに接続
コンテナにエイリアスを設定
App コンテナからホスト名で接続できる
DB Docker Compose 化 これらを1コマンドで再現できる
Mail 👉 イメージを選定 モックメールサーバの起動準備ができる
Mail コンテナを起動 SMTP サーバが起動できる
Web サーバが起動できる
Mail コンテナのポートを公開 ブラウザからアクセスできる
Mail コンテナをネットワークに接続
コンテナにエイリアスを設定
App コンテナからホスト名で接続できる
Mail Docker Compose 化 これらを1コマンドで再現できる
ほか ボリュームを作成 マウントする準備ができる
ほか ネットワークを作成 コンテナを接続する準備ができる

イメージのビルドを始める前に

イメージを作る前に、簡単にいくつか整理しておきます。

App コンテナについて

この本では Ubuntu イメージをベースにして、自分で PHP とメール送信のコマンドをインストールしたり設定を行ったりします。

PHP のインストールから行うのは学習のためであり、実運用では Docker Hub で 言語やフレームワークの公式イメージの中から選んだイメージをベースにする ことが多いです。
とはいえそれらの公式イメージがそのまま未設定で用途に合致することは多くないため、イメージのビルドは必要スキル です。

DB コンテナについて

この本では MySQL イメージを使います。
簡単な設定をするくらいで、ほぼ公式の通り使います。

実運用もほぼ同じ手間で使う ことになるでしょう。

Mail コンテナについて

この本では MailHog というイメージを取得して、一切手を入れずそのまま使います。

MailHog はモックのメールサーバを起動してくれる OSS で、このメールサーバに向かって送信したメールは宛先まで転送されません。
実際に受信できない代わりに、送信した ( はずの ) メールの内容を MailHog の Web サーバで確認することができます。

実運用でも同じように活用する ことができます。

構築

App イメージのビルド

App イメージを作るための Dockerfile は、次の内容を実現する5命令です。

  • ベースイメージの指定
  • PHP のインストール
  • PHP の設定ファイルを追加
  • msmtp のインストール
  • msmtp の設定ファイルを追加

image

また、動作確認で必要になるいくつかのコマンドもインストールしておきます。
これらは確認用途に限るものなので、全体構成図などでは表記を省きます。

まずは git clone した docker-practice リポジトリの work ディレクトリに移動し、docker/app/Dockerfile を作成してください。

Host Machine
$ touch docker/app/Dockerfile

ベースイメージの指定

ベースイメージの指定は FROM で行います。

本来は使うイメージは Docker Hub で探しますが、Ubuntu イメージは1部で使った ubuntu:20.04 を使うことにするので探すのは割愛します。

以上を踏まえ、Dockerfile を次のように編集します。

docker/app/Dockerfile
FROM ubuntu:20.04

PHP のインストール

インストールなどの Linux 操作は RUN で行います。

基本的に RUN を書く場合に求められるのは Docker の知識ではなく Linux の知識 であることが大半です。
そのため検索ワードに docker などをつける必要はなく、むしろ ubuntu php8 install のように OS 名を指定する方が良いでしょう。

以上を踏まえ、調べてわかった手順を Dockerfile の末尾に書き加えます。

docker/app/Dockerfile
RUN apt update                                       && \
    apt install -y software-properties-common        && \
    LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php && \
    apt update                                       && \
    apt install -y php8.0 php8.0-mysql

ここでは PHP のインストールを1つのまとまりと考え、RUN によるコマンドは && で結合して記述することにします。

PHP の設定ファイルを追加

設定ファイルの追加などは COPY で行います。

PHP は自分でメールを送信しているわけではなく、Sendmail や msmtp のような SMTP クライアントを使ってメールを送信するため、そのコマンドのパスを PHP の設定ファイルで指定する必要があります。

これも PHP の設定なので調べ物をするときに Docker は関係ない です。

どこに配置すれば反映できるのか調べ、次のように Dockerfile の末尾に書き加えます。

docker/app/Dockerfile
COPY ./docker/app/mail.ini /etc/php/8.0/cli/conf.d/mail.ini

それから COPY するためのファイルを作成しますが、まだ SMTP クライアントについて判明していないので、現時点では空ファイルです。

Host Machine
$ touch docker/app/mail.ini

msmtp のインストール

msmtp はメールサーバの SMTP クライアントです。

PHP のインストールと同じように手順を調べ、次のように Dockerfile の末尾に追記します。

docker/app/Dockerfile
RUN apt install -yqq msmtp msmtp-mta

また、msmtp の実体について判明したので、先に作った PHP の設定ファイルを編集します。

docker/app/mail.ini
[Mail]
sendmail_path = /usr/bin/msmtp -t

msmtp の設定ファイルを追加

メールを送信する msmtp コマンドにメールサーバのホスト名などを設定しなければなりませんが、設定項目はまだメールサーバのホスト名などがわからないので ネットワークを構築するまで書けません

そのため配置先だけ調べて空欄を含むファイルを COPY で配置するだけとします。

docker/app/Dockerfile
COPY ./docker/app/mailrc /etc/msmtprc
docker/app/mailrc
account default
host ???
port ???
from "service@d-prac.test"

動作確認用コマンドのインストール

最後に、curlpingpsvitree をインストールしておきます。

アプリケーションを動かすためには必要ありませんし、たまに必要になる程度なら使うときにインストールして使い捨てても良いのですが、この本では確認作業をシンプルにするためにイメージに含めておくことにします。

Dockerfile の末尾に次のように書き足してください。

docker/app/Dockerfile
RUN apt install -y curl iputils-ping procps vim tree

App イメージのビルド

結果的に次のようになっているはずです。

Host Machine
$ tree docker
docker
|-- app
|   |-- Dockerfile
|   |-- mail.ini
|   `-- mailrc
`-- db
docker/app/Dockerfile
FROM ubuntu:20.04

RUN apt update                                       && \
    apt install -y software-properties-common        && \
    LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php && \
    apt update                                       && \
    apt install -y php8.0 php8.0-mysql

COPY ./docker/app/mail.ini /etc/php/8.0/cli/conf.d/mail.ini

RUN apt install -yqq msmtp msmtp-mta

COPY ./docker/app/mailrc /etc/msmtprc

RUN apt install -y curl iputils-ping procps vim tree

TAG を決め、Dockerfile の場所を指定し、COPY するファイルのパスを考えて、次のようにイメージをビルドします。

Host Machine
$ docker image build             \
    --tag docker-practice:app    \
    --file docker/app/Dockerfile \
    .

ビルドできたことを確認する

image ls を使って docker-practice:app が存在することを確認してください。

DB イメージのビルド

DB イメージを作るための Dockerfile は、次の内容を実現する2命令です。

  • ベースイメージの指定
  • MySQL の設定ファイルを追加

image

まずは docker/db/Dockerfile を作成してください。

Host Machine
$ touch docker/db/Dockerfile

ベースイメージの指定

Docker Hub で mysql と検索すると、MySQL が見つかります。

Tags を見ると主に 5.7 系と 8 系がありますが、今回は mysql:5.7 を使います。

OS/ARCH の項目を見ると 8 系は linux/arm64/v8 がありますが、5.7 系にはそれがないため、container run--platform オプションと同様のアーキテクチャを明示するオプションが必要になります。

以上を踏まえ、Dockerfile を次のように編集します。

docker/db/Dockerfile
FROM --platform=linux/amd64 mysql:5.7

MySQL の設定ファイルを追加

Docker ではなく MySQL について調べ、内容と配置先を確認します。

まず内容ですが、文字コードとログの設定をしたいので次のような設定ファイルを作成します。

docker/db/my.cnf
[mysqld]
character_set_server = utf8                    
collation_server     = utf8_unicode_ci         
general_log          = 1                       
general_log_file     = /var/log/mysql/query.log
log-error            = /var/log/mysql/error.log

[client]
default-character-set = utf8

次にこれをイメージに追加するための COPY 命令を Dockerfile に追記します。

docker/db/Dockerfile
COPY ./docker/db/my.cnf /etc/my.cnf

イメージのビルド

結果的に次のようになっているはずです。

Host Machine
$ tree docker
docker
|-- app
|   |-- Dockerfile
|   |-- mail.ini
|   `-- mailrc
`-- db
    |-- Dockerfile
    `-- my.cnf
docker/db/Dockerfile
FROM --platform=linux/amd64 mysql:5.7

COPY ./docker/db/my.cnf /etc/my.cnf

TAG を決め、Dockerfile の場所を指定し、COPY するファイルのパスを考えて、次のようにビルドします。

Host Machine
$ docker image build            \
    --tag docker-practice:db    \
    --file docker/db/Dockerfile \
    .

ビルドできたことを確認する

image ls を使って docker-practice:db が存在することを確認してください。

Mail イメージの選定

先述の通り MailHog はそのまま使うため、ビルドは必要ありません。

イメージの取得も container run についでにやってもらうことにするので、image pull すら必要ありません。

mailhog/mailhog:v1.0.1 というイメージ名だけ控えておきましょう。

( 余談 ) 初めて構築するときは

この本ではいきなり Dockerfile を書きましたが、構築手順が定かではない場合はこの方法は効率が悪い です。

「PHP のインストールってこれでいいのかな」「msmtp ってどうやってインストールするんだろう」という状態なら、一度ただベースイメージを起動して自分で bash で試行錯誤する とよいでしょう。

image

Dockerfile をゼロから書く場合は、基本的には「ベースイメージをただ起動して bash で試す」「そこで動いたコマンドを Dockerfile にペーストする」というサイクルになるでしょう。

image

まとめ

このページの手順書と成果物は次のディレクトリで公開されています。

https://github.com/suzuki-hoge/docker-practice/tree/master/samples/3-2-イメージのビルド

混乱してしまったときに参考にしてください。

ポイント

  • FROM を書くときは、Docker Hub で探す
  • RUN を書くときは、Linux の知識 が必要になる
  • COPY を書くときは、その製品の知識 が必要になる
  • 手順が定かでない場合、 まずはコンテナを起動して手作業してみる のが有効

できるようになったことの確認

やること できるようになること
App 👉 イメージをビルド ✅ PHP が準備できる
✅ メール送信が準備できる
App コンテナを起動しビルド結果を確認
Web サーバを起動
Dockerfile の妥当性が確認できる
Web サーバが起動できる
App ソースコードをバインドマウント ホストマシンの .php 編集が即反映される
App コンテナのポートを公開 ブラウザからアクセスできる
App コンテナをネットワークに接続
データベースサーバの接続設定
メールサーバの接続設定
DB コンテナに接続できる
Mail コンテナに接続できる
App Docker Compose 化 これらを1コマンドで再現できる
DB 👉 イメージをビルド ✅ 文字コードとログの設定ができる
DB 環境変数を指定してコンテナを起動 Dockerfile の妥当性が確認できる
MySQL サーバが起動できる
ユーザとデータベースを作成できる
DB データ置場にボリュームをマウント テーブルがコンテナ削除で消えなくなる
DB 初期化クエリをバインドマウント コンテナ起動時にテーブルが作成される
DB コンテナをネットワークに接続
コンテナにエイリアスを設定
App コンテナからホスト名で接続できる
DB Docker Compose 化 これらを1コマンドで再現できる
Mail 👉 イメージを選定 ✅ SMTP サーバが起動できる
✅ Web サーバが起動できる
Mail コンテナを起動 SMTP サーバが起動できる
Web サーバが起動できる
Mail コンテナのポートを公開 ブラウザからアクセスできる
Mail コンテナをネットワークに接続
コンテナにエイリアスを設定
App コンテナからホスト名で接続できる
Mail Docker Compose 化 これらを1コマンドで再現できる
ほか ボリュームを作成 マウントする準備ができる
ほか ネットワークを作成 コンテナを接続する準備ができる

image