昨日はブッチさんのミライトデザインに入ってからの1年を振り返る記事でした。
ブッチさんとはお互いがミライトデザインに入る前から知り合いだったので、今同じ会社で仕事をしているのが不思議な感じですね。
この記事について
@ucan-lab さんの docker-laravel をちゃんと理解したいので調べるという目的の記事です。
前回の記事では飛ばしていた Dockerfile について調べていきます。
docker-compose.yml の他の記述に関しては前回の記事で解説しています。
Dockerfile のコマンド
各 Dockerfile の詳細を見る前に docker-laravel で使われている Dockerfile のコマンドを確認します。
-
ビルドステージを初期化して、ベース・イメージを指定
- ビルドステージを初期化っていうのはおそらく、以前のビルド結果に影響を受けづに、新規でビルドを開始するみたいなイメージのはず
-
ベース・イメージは以降の命令から影響を受ける
- ベースイメージに対してファイルをコピーしたりとか
-
イメージにメタデータを追加する。
-
key と value の組み合わせ
-
コンテナの動作に影響はない
-
shell で使われるデフォルトのコマンドを上書きできる
-
ビルドステージ内での環境変数を指定する
-
COPY <コピー元:ホストマシン> <コピー先:Docker内>
-
ホスト(自分の Mac とか) から Docker のコンテナ内にファイルやディレクトリをコピーできる
-
シェルでコマンドを実行できる
-
ホストではなくコンテナ内で実行される
-
RUN
、CMD
、ENTRYPOINT
、COPY
、ADD
命令の処理時に(コマンドを実行する場所として)使う 作業ディレクトリworking directory を指定します。 -
ディレクトリが存在しなければ作成する
php
# ① ベースイメージを指定
FROM php:8.0-fpm-bullseye
# ② メタデータを追加
LABEL maintainer="ucan-lab <yes@u-can.pro>"
# ③ デフォルトのシェルをオーバーライド
SHELL ["/bin/bash", "-oeux", "pipefail", "-c"]
# --- ④ 環境変数を設定 ---
# timezone environment
ENV TZ=UTC \
# locale
LANG=en_US.UTF-8 \
LANGUAGE=en_US:en \
LC_ALL=en_US.UTF-8 \
# composer environment
COMPOSER_ALLOW_SUPERUSER=1 \
COMPOSER_HOME=/composer
# ------
# ⑤ composer をインストール
COPY --from=composer:2.1 /usr/bin/composer /usr/bin/composer
# --- ⑥ イメージ上に任意のコマンドを実行 ---
RUN apt-get update && \
apt-get -y install git libicu-dev libonig-dev libzip-dev unzip locales && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
locale-gen en_US.UTF-8 && \
localedef -f UTF-8 -i en_US en_US.UTF-8 && \
mkdir /var/run/php-fpm && \
docker-php-ext-install intl pdo_mysql zip bcmath && \
composer config -g process-timeout 3600 && \
composer config -g repos.packagist composer https://packagist.org
# ------
# ⑦ zzz-www.conf をコンテナにコピー
COPY ./infra/docker/php/php-fpm.d/zzz-www.conf /usr/local/etc/php-fpm.d/zzz-www.conf
# ⑧ php.ini をコンテナにコピー
COPY ./infra/docker/php/php.ini /usr/local/etc/php/php.ini
# ⑨ 作業ディレクトリを指定
WORKDIR /work/backend
① ベースイメージを指定
FROM php:8.0-fpm-bullseye
PHPのイメージタグの種類として cli, apache, fpm, zts の4種類が用意されています。
-
ここで apache なんかを選択すると nginx のコンテナを立てて、unix ソケットで通信して、みたいなことは必要なくる。
- nginx のコンテナが必要なくなって、php と mysql だけで良くなる(phpのコンテナに apache がすでに入っていることになるので)
-
os は bullseye を使用している
- bullseys は Debian のバージョン11
② メタデータを追加
LABEL maintainer="ucan-lab <yes@u-can.pro>"
- ucan さんがメンテナンスしてるよって書いてあるだけ、動作に影響はない
③ デフォルトのシェルをオーバーライド
- Linux のデフォルトのシェル(
["/bin/sh", "-c"]
)からbash
に変更している -
pipefail
あたりのオプションでエラーを見やすくしたりしてる
あんまりわかってないけど、シェルの設定っぽいので今回はいいかな ...
④ 環境変数を設定
TZ=UTC
- OS(Debian) のタイムゾーンを UTC に設定している
LANG=en_US.UTF-8
, LANGUAGE
, LC_ALL
- 言語設定をしている
- 優先順とか色々あるらしい
⑤ composer をインストール
COPY --from=composer:2.1 /usr/bin/composer /usr/bin/composer
--from オプションを付けると別のイメージのファイルを指定できます。(マルチステージビルド)
composer のインストールがとてもシンプルになっています。
- dockerhub の composer:2.1 のイメージから
composer
をベースイメージにコピーしている
⑥ イメージ上に任意のコマンドを実行
RUN apt-get update && \
apt-get -y install git libicu-dev libonig-dev libzip-dev unzip locales && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
locale-gen en_US.UTF-8 && \
localedef -f UTF-8 -i en_US en_US.UTF-8 && \
mkdir /var/run/php-fpm && \
docker-php-ext-install intl pdo_mysql zip bcmath && \
composer config -g process-timeout 3600 && \
composer config -g repos.packagist composer https://packagist.org
ワンライナーで実行することによって、イメージレイヤ数を減らすことができます。
-
\
で繋いでいつのはイメージのレイヤ数を減らすため
- コンテナに対する変更の差分がレイヤ
- レイヤが増えると Docker image が大きくなってしまうため、できる限り減らしている
apt-get update
- パッケージを管理している DB を最新にする
- ライブラリ自体の更新は行わない
apt-getコマンドは、Debian系のディストリビューション(DebianやUbuntu)のパッケージ管理システムであるAPT(Advanced Package Tool)ライブラリを利用してパッケージを操作・管理するコマンドです。
-
FROM
で指定したベースイメージがbullseye(Debian のバージョン 11)
を使っているのでapt-get
が使える
apt-get -y install git libicu-dev libonig-dev libzip-dev unzip locales
-
指定されたライブラリをインストール
-
-y
問い合わせが来たら全て yes と答える -
- お馴染みの git
-
- Unicode 用の国際化コンポーネントの開発用ファイル
- なんでいるんだろ?言語設定とかで必要なんかな?
-
- 正規表現のライブラリっぽい
-
- zip の作成読み取りなど
-
- zip ファイル展開のためのライブラリ
-
- ローカルの他言語サポートのためのライブラリ
(どのタイミングで使われるのかあんまりわかってないな。無いと Laravel 動かないのか?)
apt-get clean
パッケージをインストールするために拾ってきたアーカイブファイル( *.tar.gz とか)を削除
rm -rf /var/lib/apt/lists/*
(ubuntu
の記事だけど、Ubuntu
は Debian
をベースに派生したらしいから、おそらく似たようなもん)
https://eng-entrance.com/linux-debian-ubuntu
-
/etc/apt/sources.list
(apt-get
で更新したファイル)に基づいて、パッケージインデックスファイル
がダウンロードされる -
インデックスファイル
は/var/lib/apt/lists
に保存される- インデックスファイルはパッケージの情報で、インデックスファイルからインストールされているソフトウェアのバージョンを比較して、
新しいバージョンが存在するかなどを確認しているらしい
- インデックスファイルはパッケージの情報で、インデックスファイルからインストールされているソフトウェアのバージョンを比較して、
-
ここでは、
rm -rf
で/var/lib/apt/lists
を削除してる-
/var/lib/apt/lists
を削除して、イメージのサイズを減らすのがベストプラクティスらしい - もう使わないから消しても問題ないってことなんだろうな
-
locale-gen en_US.UTF-8
DockerでbuildしたイメージはロケールがPOSIXになっている。これに起因して、文字コード変換まわりの不具合が発生したりする。
そしてこれがDockerfileに書く設定
RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
- `④ 環境変数を設定` はこのためにやってるっぽい
- `locale-gen` コマンドが何をやってるのかがよくわからない
https://qiita.com/aosho235/items/58e2e7acd5c2ee3641ff#%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AB%E4%BD%BF%E3%81%84%E3%81%9F%E3%81%84%E3%83%AD%E3%82%B1%E3%83%BC%E3%83%AB%E3%81%8C%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E5%A0%B4%E5%90%88
>locale-genはシェルスクリプトになっていて、内部で
>```
localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
に相当することをやっている。
- ちょっとよくわからないけど、一旦ここまで
mkdir /var/run/php-fpm
-
/var/run/php-fpm
ディレクトリを作成している - docker-compose.yml で UNIX ソケットでマウントしてたディレクトリ
- デフォルトでは作成されないのかな?
volumes:
- type: volume
source: php-fpm-socket
target: /var/run/php-fpm
volume:
nocopy: true
docker-php-ext-install intl pdo_mysql zip bcmath
- Laravel の動作に必要な PHP の拡張機能があるらしい
- このコマンドで全てインストールしてるわけじゃなさそう
docker-php-ext-install
- 公式が用意してくれている PHP の拡張ライブラリをインストールするためのコマンド
- インストールしたライブラリの有効化までやってくれているっぽい
intl
- 国際化関数
ケール関連のさまざまな操作を行えるようにします。 フォーマット、音訳、エンコード変換、カレンダーの処理、 » UCA 準拠の照合順序 (collation)、 テキストの区切り、ロケール識別子やタイムゾーンや書記素を用いた操作などが可能です。
- 入ってないと Laravel でエラーになったりするらしい
pdo_mysql
PDO_MYSQL は、PHP から MySQL データベースへのアクセスを可能にするための PHP Data Objects (PDO) インターフェイス を実装したドライバです。
zip
この拡張モジュールにより、ZIP 圧縮されたアーカイブとその内部のファイルに対する透過的な読み書きが可能となります。
bcmath
任意の精度の演算をサポートするために、PHP は 2147483647 (または 0x7FFFFFFF) までの 任意のサイズおよび精度の小数桁をサポートする BCMath を提供します。 十分なメモリがあれば、文字列表現もサポートします。
有効(別名 well-formed) な BCMath数 は、以下の正規表現にマッチする文字列です。 /^[+-]?[0-9](.[0-9])?$/.
composer config -g process-timeout 3600
composer のプロセスがタイムアウトしないように上限時間を伸ばしている
config コマンドは、ローカルの composer.json ファイルまたはグローバルな config.json ファイルにある Composer の設定とリポジトリを編集することができます。
デフォルトでは
$COMPOSER_HOME/config.json
にあるグローバルな設定ファイルに対して操作します。このオプションがない場合は、ローカルの composer.json ファイルか、-file で指定したファイルに作用します。
プロセス実行の秒単位のタイムアウト。デフォルトは300(5分)です。 git clonesのような期間プロセスは、Composerがそれらが消滅したと想定する前に実行できます。接続が遅い場合やベンダーが巨大な場合は、これを高くする必要があります。
composer config -g repos.packagist composer https://packagist.org
PHPのライブラリリポジトリであるhttps://packagist.orgのミラーサイトです。packagist.orgの代わりにこちらを参照することで、composer updateの応答速度が速くなります。特にフランスから遠い、アジア圏では顕著な効果が得られます。
有効にするには以下のコマンドを打ち込んでください。
enable
$ composer config -g repos.packagist composer https://packagist.jp
⑦ zzz-www.conf
をコンテナにコピー
COPY ./infra/docker/php/php-fpm.d/zzz-www.conf /usr/local/etc/php-fpm.d/zzz-www.conf
-
php-fpm の設定項目をマウント している
- 設定ファイルが
zzz-www.conf
になってるのは公式イメージにある設定を上書きするためらしい
- 設定ファイルが
⑧ php.ini
をコンテナにコピー
-
php.ini
- php の設定をするファイル
⑨ 作業ディレクトリを指定
WORKDIR 命令は、Dockerfile 内で以降に続く RUN 、 CMD 、 ENTRYPOINT 、 COPY 、 ADD 命令の処理時に(コマンドを実行する場所として)使う 作業ディレクトリworking directory を指定します。 WORKDIR が存在していなければ作成されます。これは、以降の Dockerfile で使われなくてもです。
- ここでは WORKDIR がなければ作成されるだけ
php-fpm.d/zzz-www.conf
について
[www] ; ① プール名
listen = /var/run/php-fpm/php-fpm.sock ; ② FastCGI のリクエストを受け入れるアドレス
; --- ③ パーミッションの設定 ---
listen.owner = www-data
listen.group = www-data
listen.mode = 0666
; ------
access.log = /dev/stdout
① プール名
[www]
www
って名前をプロセスプールにつけている
② FastCGI のリクエストを受け入れるアドレス
listen = /var/run/php-fpm/php-fpm.sock
FastCGI リクエストを受け入れるアドレス。 'ip.add.re.ss:port', 'port', '/path/to/unix/socket' 形式の構文が使えます。 このオプションは、各プール単位で必須となります。
-
PHP-fpm と Nginx を連携させるには、 TCP か UNIX ドメインソケットのどちらかで通信する
-
docker-compose.yml
で/var/run/php-fpm
をマウントさせているのは UNIX ドメインソケットで通信するため -
ここで、 UNIX ドメインソケットのパスを指定することで、 UNIX ドメインソケットでの通信が行えている
③ パーミッションの設定
unix ソケットを使う場合に、そのパーミッションを設定します。Linux では、 読み書きアクセス権限を設定しないとウェブサーバーからの接続を受け付けることができません。 多くの BSD 由来のシステムでは、パーミッションにかかわらず接続を受け付けることができます。 デフォルト値: ユーザーとグループは実行しているユーザーと同じ、モードは 0660
-
www-data
は Ubuntu (おそらく Debian でも) 上の Web サーバー(Apache、nginxなど)がデフォルトで通常の操作に使用するユーザー -
listen.mode = 0660
でも動くのかな?
ログ
php.ini
について
php.ini
は ucan さんの別記事で詳しく解説してありましたのでここでは深堀はしません。
おわり
まだ MySql と Nginx の Dockerfile も残っているので、せっかくなのでアドカレとは別で書きたいと思います。(そのうち)
明日は yuki の GAE についての記事らしいです。
よろしくお願いします!