メインメニュー
XAMPP アレンジ
IED
WSL2
-
道具箱
リポジトリ編
フレームワーク編
公開ソフトウェア
メタ
リンク
- PHP ライブラリ
- PHP 言語
docker:20:build目次
Docker コンテナイメージの作成(Build)
Docker 20.10.1
— y2sunlight 2020-12-20
関連記事
- Docker コンテナイメージの作成(Bulid)
リンク
- Docker コマンドリファレンス — Docker日本語ドキュメント
- Dockerfile リファレンス — Docker日本語ドキュメント
- PHPのDocker公式イメージ — Docker Hub
PHPを例にとって、Dockerコンテナの作成方法を説明します。この例では、Docker Hubの公開リポジトリ(パブリックリポジトリ)で配布されているPHPコンテナを使って、自分用に設定したPHPのDockerイメージを作成します。
本章の実行環境
- Windows10Pro / WSL2
- Ubuntu 20.04.1 LTS
本章の実行例は WindowsターミナルのUbuntuターミナルで実行しています。dockerの初期設定については、こちらを参照して下さい。
ベースイメージの取得
Dockerイメージは、多層構造になっていて、それらの各層(レイア)が透過的に重なり1つのファイルシステムを構成しています。各層はディレクトリやファイルを含み、またはメタ情報だけの層もあります。Docker イメージを作成する場合は、ベースとなる層の上に自分のイメージを作成します。このベースとなるイメージを以降は「ベースイメージ」と呼びます。
多くの場合、Dockerイメージは、その基になるベースイメージから始まります。そのイメージは親イメージと呼ばれ、Docker Hub から取得できます。本章では、以下のベースイメージを使用します。
- https://hub.docker.com/_/php — PHP Docker公式イメージ
この中の Apache+PHP7.4 用のコンテナから、タグ
7.4-apache
のイメージをdocker pull コマンドでダウンロードします:$ docker pull php:7.4-apache
PHPコンテナのベースイメージはパッケージの依存関係などもありOSのベースが本番環境ともに同じものを利用します。ここで選択した
php:7.4-apache
のOSのベースは、このイメージの Dockerfile を調べるとdebian:buster-slim
だという事が分かります。このベースは Debian 10 で処理系なしの軽量な実行環境用のイメージです。OSのベースイメージ選びについては、以下のサイトが参考になりました:
ベースイメージの調査
ダウンロードしたDockerイメージ
php:7.4-apache
を docker run コマンドでコンテナとして開始します。この時、操作し易いようにコンテナに名前(php74
)を付け、またホストからブラウザでアクセスできるようにポート8080
にフォワードしています:$ docker run --name php74 -d -p 8080:80 php:7.4-apache $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 373a10d11ec1 php:7.4-apache "docker-php-entrypoi…" 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp php74
次に、docker exec コマンドで
php74
コンテナ内で、bash
コマンドを実行します:$ docker exec -it php74 bash
これで、ベースイメージを調査する準備ができました。
Apacheの設定ファイル(
apache2.conf
)の場所を確認します:# ls -l /etc/apache2/apache2.conf -rw-r--r-- 1 root root 7224 Aug 25 20:08 /etc/apache2/apache2.conf
Apacheのサイト構成ファイル(
000-default.conf
)の場所を確認します:# ls -l /etc/apache2/sites-available/000-default.conf -rw-r--r-- 1 1000 1000 1469 Dec 21 06:06 /etc/apache2/sites-available/000-default.conf
以下のようにして、PHPの設定ファイルの場所を調べます。
# php -r "phpinfo();" | grep php.ini Configuration File (php.ini) Path => /usr/local/etc/php # ls /usr/local/etc/php -l total 148 drwxr-xr-x 1 root root 4096 Dec 11 08:24 conf.d -rw-r--r-- 1 root root 72553 Dec 11 08:24 php.ini-development -rw-r--r-- 1 root root 72583 Dec 11 08:24 php.ini-production
これで、ApacheとPHPの設定ファイルの場所と名前が分かったので、それをホスト側にコピーします。この作業は、別のターミナルを起動してホスト側で、docker cp コマンドを使って行います:
$ docker cp php74:/etc/apache2/apache2.conf . $ docker cp php74:/etc/apache2/sites-available/000-default.conf . $ docker cp php74:/usr/local/etc/php/php.ini-development ./ $ docker cp php74:/usr/local/etc/php/php.ini-production ./
コンテナ内のファイルの変更と追加
設定ファイルの変更
ホスト側で、先にコンテナから取得した以下のファイルを編集します。
- apache2.conf — Apacheの設定ファイル
- 000-default.conf — Apacheのサイト構成ファイル
- php.ini-development — PHPの設定ファイル
ここでは、例として以下のように
000-default.conf
を修正します。- 000-default.conf
<VirtualHost *:80> ... # For testing docker <Directory /var/www/html> Options Indexes FollowSymLinks Includes ExecCGI AllowOverride All Require all granted </Directory> ... </VirtualHost>
- ドキュメントルート
/var/www/html
のファイル一覧表示を許可 - その他、ほとんどの操作を許可しています
編集が終わったら、これらの設定ファイルをコンテナにコピーします。
$ docker cp ./apache2.conf php74:/etc/apache2/ $ docker cp ./000-default.conf php74:/etc/apache2/sites-available/ $ docker cp ./php.ini-development php74:/usr/local/etc/php/php.ini
コンテナを再起動します:
$ docker restart php74
Winodws側のプラウザから
http://localhost:8080/
にアクセスするとコンテナのドキュメントルーツのindexが表示されます。
htmlとphpファイルの設置
以下のように、hello.html と info.php を新しく作成します:
作成したファイルをコンテナのドキュメントルートにコピーします:
$ docker cp ./hello.html php74:/var/www/html/ $ docker cp ./info.php php74:/var/www/html/
Winodws側のプラウザから
http://localhost:8080/
にアクセスするとコンテナのドキュメントルーツのindexが表示されます。
PHP拡張モジュールの追加
DockerイメージにPHP拡張モジュールを追加する場合の視点は次の4つがあります:
- コンパイル済の拡張モジュール — ベースイメージのPHPに既にコンパイルされて追加されている
- PHPコア拡張モジュール — 公式PHP Dockerイメージを利用して簡単にインストールできる
- PECL拡張モジュール — PECLから入手できる(peclコマンドを使います)
- その他の拡張モジュール — phpize、make コマンドなどを使って手動でインストールする
DockerでのPHP拡張モジュールの追加については、是非、以下のURLの「How to install more PHP extensions」の項を一読されることを推奨します。
以下に「その他の拡張モジュール」を除くそれぞれの場合について説明します。
コンパイル済の拡張モジュール
多くの拡張モジュールは既にコンパイルされてモジュールに格納されています。本章では、apache ドキュメントルートに作成した
info.php
からそれを調べることができます:http://localhost:8080/info.php
また、コンテナ内部から
php -m
コマンドでこれを確認することもできます。実行例:# php -m [PHP Modules] Core ctype curl date dom fileinfo filter ftp hash iconv json libxml mbstring mysqlnd openssl pcre PDO pdo_sqlite Phar posix readline Reflection session SimpleXML sodium SPL sqlite3 standard tokenizer xml xmlreader xmlwriter zlib
これらのモジュールについては既に存在するので追加の必要はありません。
PHPコア拡張モジュールの追加
ここで言う「 PHPコア拡張モジュール」とは公式PHP Dockerイメージ を利用して、インストールできる拡張モジュールを指しています。「公式PHP Dockerイメージ」を親に持つベースイメージを使う場合は、この方法が利用できます。どの拡張モジュールが対象となっているかは、以下の
docker-php-extension-installer
プロジェクトのSupported PHP extensions
を参照して下さい:これらの拡張モジュールは、圧縮されてDockerイメージの中に含まれており、以下の3つのヘルパースクリプトを使って簡単にインストールできます。
docker-php-ext-configure
— 拡張モジュールにカスタム構成が必要な場合にdocker-php-ext-install
の前に実行します。docker-php-ext-install
— 拡張モジュールをインストールします。docker-php-ext-enable
—pecl
コマンドなど、docker-php-ext-instal
以外で拡張モジュールをインストールした後に使用し、php.ini
に拡張モジュールの有効性を設定します。
例:gdのインストール
例として PHP拡張モジュール
gd
をインストールします。gd は使用する画像イメージの種類によって様々なバリエーションがあります。以下のサイトに詳しい説明があります。ここでは、png と jpeg が使えるようにします。以下の作業は、コンテナ内で行います。
まずは、パッケージの一覧を更新します:
# apt update
gd の使用するパッケージをインストールします:
# apt install -y zlib1g-dev libpng-dev libjpeg62-turbo-dev
gd をインストールし、PHP拡張モジュールとして有効にします:
# docker-php-ext-configure gd --with-jpeg # docker-php-ext-install -j$(nproc) gd
docker-php-ext-configure
はdocker-php-ext-install
の前で実行する必要があります。docker-php-ext-install
の-j$(nproc)
オプションは同時実行できる処理数で、CPU数を指定しています。docker-php-ext-enable
はdocker-php-ext-install
によって実行されます。
インストール後、
extension_dir
の中にgd.so
がインストールされています:# ls /usr/local/lib/php/extensions/no-debug-non-zts-20190902/*.so -l -rwxr-xr-x 1 root root 426544 Dec 21 08:41 /usr/local/lib/php/extensions/no-debug-non-zts-20190902/gd.so ...
また、php.iniのインクルードファイルが追加されています:
# ls -l /usr/local/etc/php/conf.d/*.ini -rw-r--r-- 1 root root 16 Dec 21 08:41 /usr/local/etc/php/conf.d/docker-php-ext-gd.ini ...
- docker-php-ext-gd.ini
extension=gd.so
exit
でコンテナから出て、ホストでコンテナ(php74
)を再起動します。$ docker restart php74
Winodws側のプラウザから
http://localhost:8080/info.php
にアクセスするとgd
がインストールされているのが確認できます。
PECL拡張モジュールの追加
PECLからインストールするには、[https://www.php.net/manual/ja/install.pecl.pear.php|pecl コマンド]を使用します。
pecl install
を使用してダウンロードしてコンパイルしてから、docker-php-ext-enable
を使用して拡張モジュールを有効にします。例:memcachedのインストール
PECL からインストール例として memcached を取り上げます。以下の作業は、コンテナ内で行います。
まず、パッケージの一覧を更新し、memcached が依存しているパッケージをインストールしておきます:
# apt update # apt install -y libmemcached-dev
pecl コマンドを使用して、memcached インストールします:
# pecl install memcached
以下は、インストールの実行例です:
# pecl install memcached pecl/memcached can optionally use PHP extension "igbinary" (version >= 2.0) pecl/memcached can optionally use PHP extension "msgpack" (version >= 2.0) ... libmemcached directory [no] : # [Enter]入力 zlib directory [no] : # [Enter]入力 use system fastlz [no] : # [Enter]入力 enable igbinary serializer [no] : # [Enter]入力 enable msgpack serializer [no] : # [Enter]入力 enable json serializer [no] : # [Enter]入力 enable server protocol [no] : # [Enter]入力 enable sasl [yes] : # [Enter]入力 enable sessions [yes] : # [Enter]入力 ... Build process completed successfully Installing '/usr/local/lib/php/extensions/no-debug-non-zts-20190902/memcached.so' install ok: channel://pecl.php.net/memcached-3.1.5 configuration option "php_ini" is not set to php.ini location You should add "extension=memcached.so" to php.ini
- インストールの最中にオプションを聞かれますが、全て[Enter]を入力します。
最後に、
docker-php-ext-enable
を使用して拡張モジュールを有効にします:# docker-php-ext-enable memcached
インストール後、extension_dir の中に gd.so がインストールされています:
# ls /usr/local/lib/php/extensions/no-debug-non-zts-20190902/*.so -l -rw-r--r-- 1 root root 729464 Dec 22 13:29 /usr/local/lib/php/extensions/no-debug-non-zts-20190902/memcached.so ...
また、php.iniのインクルードファイルが追加されています:
# ls -l /usr/local/etc/php/conf.d/*.ini -rw-r--r-- 1 root root 20 Dec 21 11:32 docker-php-ext-memcached.ini ...
- docker-php-ext-memcached.ini
extension=memcached
exit でコンテナから出て、ホストでコンテナ(php74)を再起動します:
$ docker restart php74
Winodws側のプラウザから
http://localhost:8080/info.php
にアクセスするとmemcached
がインストールされているのが確認できます。
イメージの保存
以下の作業はホストで行います。
開始中のコンテナ(
php74
)を停止します。$ docker stop php74
これまでに作成したコンテナをDockerイメージとして保存するには、docker commit コマンドを使います。
$ docker commit php74 myphp74:2020-12-22 sha256:d743369242c56be71e47f1e7ad0f5b218ff8a61c923643fc475c6d01dbb23cda
保存したDockerイメージを docker images コマンドで確認します。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE myphp74 2020-12-22 62df1ffadc6f About a minute ago 439MB ...
保存したDockerイメージを起動します。
$ docker run --name myphp74 -d -p 8080:80 myphp74:2020-12-22 23d84d5ce0837cdbf171695c417fe387793aadbdf497b341d24d398ef9ae809a
Winodws側のプラウザから
http://localhost:8080/info.php
にアクセスして、gd
とmemcached
がインストールされているか確認して下さい。
Dockerfile
これまでの項では、手動でDockerコンテナを作成しイメージとして保存しました。これら一連のDockerイメージの作成過程を自動化してくれるのが「Dockerfile」です。Dockerfile とは、Docker イメージを作成する時のコマンドを1つのファイルにまとめたもので、Docker コンテナの構成情報を記述するためのファイルです。
これまでの項で作成してものと全く同じDockerイメージを本項では Dockerfile を使って作成します。以下の作業は全てホストで行います。
作業ディレクトリの準備
ホームディレクトリ下に以下の作業ディレクトリを作成します:
~/docker/php7.4
このディレクトリの中にこれまでに作成した次のファイルを準備します。
- Dockerfile — コンテナ構成ファイル
- apache2.conf — Apacheの設定ファイル
- 000-default.conf — Apacheのサイト構成ファイル
- php.ini-development — PHPの設定ファイル(開発用)
- php.ini-production — PHPの設定ファイル(本番用)
- hello.html — テスト用のhtml ファイル
- info.php — テスト用のphpファイル
Dockerfile
以下のように、Dockerfile を編集します:
- Dockerfile
FROM php:7.4-apache # # Apache/PHP Base Settings # COPY ./apache2.conf /etc/apache2/ COPY ./000-default.conf /etc/apache2/sites-available/ COPY ./php.ini-development /usr/local/etc/php/php.ini # # /var/www/html/ # COPY ./hello.html /var/www/html/ COPY ./info.php /var/www/html/ # # Install PHP Extensions # # gd # RUN apt-get update RUN apt-get install -y zlib1g-dev libpng-dev libjpeg62-turbo-dev \ && docker-php-ext-configure gd --with-jpeg \ && docker-php-ext-install -j$(nproc) gd # # memcached # RUN apt-get install -y libmemcached-dev \ && pecl install memcached \ && docker-php-ext-enable memcached
FROM
— イメージ構築の初期化を実行し、ベースイメージを設定します。Dockerfileは必ずFROM
命令から始まります。COPY
— ホスト内のファイルやディレクトリをコンテナ内のファイルシステムに追加します。RUN
— 現在の最新イメージにおいて、コンテナ内でコマンドを実行します。コマンドが成功するとイメージは確定され、Dockerfile の次のステップで利用されます。
Dockerfileでapt
を使うと次の警告が出るのでapt-get
を使いました。WARNING: apt does not have a stable CLI interface. Use with caution in scripts.また、apt-get
を使うと今度は次の警告がでます。buildの動作的にはは問題なさそうですが調査中です。debconf: delaying package configuration, since apt-utils is not installedDockerfile の詳細については、以下を参照して下さい:
- Dockerfile リファレンス — Docker日本語ドキュメント
Dockerイメージの作成
Dockerfileの準備が出来たら、docker build コマンドを使って新しい Docker イメージを構築します。
$ docker build -t myphp74:2020-12-23 .
-t
— '名前:タグ' 形式でイメージの名前とタグ(オプション)を指定します。- コマンドの最後の引数(
.
)はソースコードのパス(ここではカレントディレクトリ)を指定します。
docker images コマンドでDockerイメージの一覧を表示します:
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE REPOSITORY TAG IMAGE ID CREATED SIZE myphp74 2020-12-23 d849c91871fd 15 minutes ago 440MB myphp74 2020-12-22 62df1ffadc6f 13 hours ago 439MB ...
docker history コマンドでイメージ内のレイヤーを表示します:
$ docker history myphp74:2020-12-23 IMAGE CREATED CREATED BY SIZE COMMENT d849c91871fd 17 minutes ago /bin/sh -c apt-get install -y libmemcached-d… 4.19MB 30fc1a25dfb9 18 minutes ago /bin/sh -c apt-get install -y zlib1g-dev lib… 4.23MB 17d39386f699 18 minutes ago /bin/sh -c apt-get update 17.5MB 778c23eca0cd 24 minutes ago /bin/sh -c #(nop) COPY file:c9b0bd401ba1924c… 17B 5645b898b5af 24 minutes ago /bin/sh -c #(nop) COPY file:398875164d45e85a… 58B 9fc74c528658 24 minutes ago /bin/sh -c #(nop) COPY file:f9dcd09c7428c2df… 72.6kB e0878c88c727 24 minutes ago /bin/sh -c #(nop) COPY file:0c73f4a9191f660f… 1.54kB 89628e4477f9 24 minutes ago /bin/sh -c #(nop) COPY file:7a59a6bc15702a48… 7.22kB fd505f1f4cd8 11 days ago /bin/sh -c #(nop) CMD ["apache2-foreground"] 0B <missing> 11 days ago /bin/sh -c #(nop) EXPOSE 80 0B <missing> 11 days ago /bin/sh -c #(nop) WORKDIR /var/www/html 0B ... <missing> 12 days ago /bin/sh -c #(nop) ADD file:3a7bff4e139bcacc5… 69.2MB
Dockerfileに記述した降順にレイヤー作成されているのが分かります。
CMD [“apache2-foreground”]
以下のレイヤーはベースイメージのものです。
Dockerイメージの起動
Dockerfileから構築したDockerイメージを起動し、Winodws側のプラウザから
http://localhost:8080
にアクセスして確認して下さい。$ docker run --name myphp74a -d -p 8080:80 myphp74:2020-12-23 7980e3ed36186de445238eae2193b3f505fed04ac03a50c5ac3adb6cc7a405dd
このように Dockerfile を使えば、Dockerイメージを素早く作れるだけでなく、GitHubなどのリポジトリによってチーム内で共有することもできます。
イメージのアップロード
ここまでで、新しいDockerイメージの作成に関する説明は終わりました。後は、DockerイメージをDocker Hubにアップロードするだけとなりましたが、Docker Hub に関して本章で説明するのは情報過多なので、改めて以下の章で説明することにします:
docker/20/build.txt · 最終更新: 2020/12/26 21:47 by y2sunlight
コメント