先日、Dockerを使ったコマンドだけでコンテナを構築する記事をまとめましたが、今回はファイルからコンテナを構築するポイントをまとめたいと思います。
複数のコンテナを同時に構築するのは"docker-compose"コマンドを使う
Dockerを調べたらよく見かける、"docker-compose.yml"や"Dockerfile"ですが、ファイルでコンテナを構築する場合はこれらのファイルと"docker-compose"というコマンドを使用します。
このコマンドはDockerDesktopをインストールしたら入っているので別途なにかを入れる必要はありません。
WEBアプリはwebサーバー + php + mysqlで構築されているものも多いですが、
その代表的なアプリとしてブログのWordPressがあります。
そのWordPressをDockerで構築し、ポイントをまとめたいと思います。
以下の手順に沿って行えば構築できますが、ファイルを作成する時間もとれないひとは完成形のベースフォルダをGithubにあげましたので、
wordpressのダウンロードしてファイルを配置して"docker compose up -d"コマンドをたたけば構築できます。
apache + php + mysqlのベース環境としても使用していただけると思います。
github.com
ベースフォルダを作成
どこでもいいのでベースフォルダを作成します。
このフォルダ名は作成されるコンテナのプレフィックスとなります。
今回は"wordpress"という名称にします。
docker-compose.ymlを作成
ベースフォルダの中に"docker-compose.yml"ファイルを作成します。
中身は以下を貼り付けてください。
version: '3.7'
services:
mysql:
image: mysql:5.7
volumes:
- mysql_data:/var/lib/mysql
- .\mysql\initdb.d:/docker-entrypoint-initdb.d
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: "password"
php-apache:
build: .\php
volumes:
- .\htdocs:/var/www/html
restart: always
ports:
- "80:80"
depends_on:
- mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
PMA_HOST: mysql
restart: always
ports:
- "8080:80"
depends_on:
- mysql
volumes:
mysql_data: {}
yaml形式というあまり見慣れない記述だと思いますが、xmlやjsonと同様でデータ構造を記述する言語です。
jsonに近い感じですが、インデントで階層を表現するため、括弧がないのとコメント(#)が記述できるのが異なる点ですかね。ちなみに先頭の"-"は配列を表します。
内容をさっくり説明すると、dbサーバ(mysql)とphpmyadminサーバとwebサーバ(apache+php)の3つコンテナを同時に作成する内容になっています。
wordpress構築にあたってphpmyadminは必須ではないですが、phpでmysqlを扱うならほぼ必須なものなのでついでに追加しています。
servicesでそれぞれに名前をつけてコンテナを定義しています。
個々の定義でイメージ、ホストフォルダとのマッピング、ポートマッピング、依存関係などを設定します。
volumesで”mysql_data”を定義しているのはこれは外付けhddみたいなもので、コンテナ内にデータを置いておくとコンテナを削除したときにデータが消えるので、ボリュームとして保存しています。
今回はmysqlのデータファイルをマッピングしてその部分だけを保存する設定としています。
最低限これだけ知っていれば問題ないと思いますが、ほかにもいろんな設定ができるので、気になるひとは以下のドキュメントを参照してください。
docs.docker.jp
mysqlのコンテナ作成時にデータベースを構築する
mysqlのコンテナ構築後はデータベースが作成されていないのでそのままだとアプリで使用できません。
構築したmysqlに接続し、データベースを作成後にテーブルを作成、その後データをインポートするSQLを実行すればよいのですが、そのSQLを構築時に実行する設定ができます。
コンテナ内の"/docker-entrypoint-initdb.d"にsqlを格納することで構築後に実行されるという仕組みです。
sqlファイルを格納するため、"wordpress"フォルダの中に"mysql"フォルダを作成します。
”mysql"フォルダの中に"initdb.d"フォルダを作成して、その中に"init_db.sql"を作成します。
中身は以下を貼り付けます。
CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8;
wordpressに使用するデータベースを作成するSQLを記述しています。テーブルやデータはwordpressが作成してくれるので。
dockerfileでコンテナ構築後にコマンドを実行する
コンテナ構築後にコマンドを実行するには構築後にコンテナ内に入ってコマンドを叩けばOKなのですが、これも構築時にコマンドを実行することができます。
上記の"php-apache"コンテナだけ"image"の指定がないですが、代わりに"build"を指定しています。ここでDockerfileを使用します。Dockerfileはイメージをカスタマイズする際に使用する感じですかね。
"wordpress"フォルダの中に"php"フォルダを作成し、その中に"Dockerfile"を作成します。
中身は以下を貼り付けます。
FROM php:7.4-apache
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
libonig-dev \
&& apt-get clean
RUN docker-php-ext-install pdo_mysql mysqli gd iconv
phpとapacheがいっしょになったイメージを使っていますが、phpは外部のモジュールを入れて使うことが多いです。
そのため、apt-getコマンドで必要なライブラリをインストールしています。apt-getはcentosでいうとyumコマンドでパッケージを管理するコマンドです。
docker-php-ext-installコマンドはPHP拡張モジュールをインストールするコマンドです。
wordpressは以下からダウンロードできます。
ja.wordpress.org
wordpressフォルダの中にhtdocsフォルダを作成し、そこに解凍してできた"wordpress"フォルダの中身をすべて移動します。
htdocsフォルダの中にindex.phpがある配置になります。
最終的に以下のようなフォルダ構成になっていればOKです。
wordpress
│ docker-compose.yml
│
├─htdocs
├─mysql
│ └─initdb.d
│ init_db.sql
│
└─php
Dockerfile
docker-composeコマンドを実行して構築する
PowerShellで"wordpress"フォルダに移動して以下のコマンドを実行します。
>docker-compose up -d
上記のコマンドだけで構築が完了すると思います。
ちなみに以下のコマンドがでたら構築は終わっていますが、内部でサービスの起動とか走っているのでしばらくまったらつながるようになります。30sくらいまてばOKです。
Creating wordpress_mysql_1 ... done
Creating wordpress_phpmyadmin_1 ... done
Creating wordpress_php-apache_1 ... done
ダッシュボードを開くと"wordpress"でグループ化されたコンポーネントが確認できると思います。

最初にも記載しましたが、このグループ化された名称は"docker-compose.yml"があるフォルダ名で決まるのでフォルダ名はわかりやすく、重複しないようにつけたほうがいいです。
ログを確認する
以下のコマンドでログの確認ができます。
>docker-compose logs
ただ、ダッシュボードで確認したほうが、検索できるので便利です。

たとえば、"entry"で検索すると、以下のような出力がされていればデータベース作成用のSQLが実行されていることが確認できます。
mysql_1 | 2020-05-17 15:10:43+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-Entrypoint.sh: running /docker-Entrypoint-initdb.d/init_db.sql
http://localhost/ にアクセスすると以下のwordpressへようこそ。という画面が表示されます。

さあ、始めましょう!をクリックします。
データベースの接続情報を入力します。
以下のように入力します。
ポイントはホスト名は"localhost"でなく、コンテナのサービス名"mysql"を指定します。

送信ボタンをクリックして以下の画面になればOKです。

インストール実行をクリックする。
必要な情報をいれます。中身は自由でOKです。

Wordpressをインストールをクリックする。
あとはそのまま続けてログインできれば構築完了です。

よく使うdocker-composeコマンド
停止する。
>docker-compose stop
削除する。停止もされます。コンテナ内のデータが消えるので注意!(volumesでマッピングしている場合はコンテナ外にデータがあるので大丈夫です)
>docker-compose down
中に入ってコマンドをたたく。以下の"mysql”はサービス名を指定します。
>docker-compose exec mysql /bin/bash
まぁコマンド覚えなくてもぜんぶダッシュボードからなんとかなります。
あとファイルのコピーとかはdockerコマンドでできます。docker-composeは複数のコンテナをまとめて操作するコマンドで
個々のコンテナの操作はdockerコマンドという感じですかね。
今作った環境をMariaDBとnginxに載せ替えたいと思います。
"wordpress"フォルダをそのまま変更してもいいですし、コピーしてもいいです。
docker-compose.ymlを以下に編集します。
ersion: '3.7'
services:
mysql:
image: mariadb
volumes:
- mysql_data:/var/lib/mysql
- .\mysql\initdb.d:/docker-entrypoint-initdb.d
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: "password"
web:
image: nginx
volumes:
- .\web\default.conf:/etc/nginx/conf.d/default.conf
- .\htdocs:/var/www/html
restart: always
ports:
- "80:80"
depends_on:
- mysql
- app
app:
build: .\php
volumes:
- .\htdocs:/var/www/html
restart: always
depends_on:
- mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
PMA_HOST: mysql
restart: always
ports:
- "8080:80"
depends_on:
- mysql
volumes:
mysql_data: {}
apache + mysql版と変えたところは以下な感じです。
nginx用の設定ファイルは"wordpress"フォルダに"web"フォルダを作成し、"default.conf"を作成します。
中身は以下を貼り付けます。
server {
listen 80;
server_name _;
root /var/www/html;
index index.php;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(\.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
これで"docker-compose up -d"で起動すれば、nginx + MariaDBでwordpressを構築完了です。
最後に
docker-composeを使うことでサーバ構築が楽になってアプリ開発に専念できそうです。
最後にnginx + MariaDBに変更しましたが、手軽にサーバ載せ替えとかできるんでこりゃ便利です。
XAMPPで構築するより融通がいろいろと効きそうですね。
Dockerについてこれで一通り知識がインプットできた気がします。
ほかにも便利な機能はあるかもなのであったらまた記録してきたいと思います。