前回の記事からの続きなので下記もよろしければ!
さらっとDocker入門
PHP+Apacheコンテナの作成
前回のおさらいですが、Apacheコンテナを作るには次のコマンドを実行しました。
$ docker container run --name test1 -d -p 8080:80 -v /Users/ユーザー名/htdocs:/usr/local/apache2/htdocs httpd
PHPを実行できるようにするには、最初からPHPをApacheがセットになったイメージがあるのでそれを使うと早いです。
現在(2021年3月)の最新版はPHP 8.0.3なのでhttpd
の部分をphp:8.0.3-apache
にして、ドキュメントルートも/var/www/html
に変更します。
$ docker container run --name test1 -d -p 8080:80 -v /Users/ユーザー名/htdocs:/var/www/html php:8.0.3-apache
ホストでしていしたディレクトリ(/Users/ユーザー名/htdocs
)に次のPHPファイルを作ってください。
index.php
<?php phpinfo();
ブラウザでhttp://localhost:8080
にアクセスしてみましょう。
PHPの情報が表示されていれば成功です。
とりあえずPHPを動かすだけなら簡単ですね。
php.iniの設定
例えばPHPの設定はphp.ini
ファイルで設定するのですが、今の状態だと何も設定していない状態なので設定してみましょう。
前回のコンテナへのファイルコピーを思い出してください。
コンテナに入っているphp.ini-development
をホストにコピーしましょう。
$ docker container cp test1:/usr/local/etc/php/php.ini-development ./
php.ini-development
をphp.ini
にリネームして必要な設定をしましょう。
ここではtimezoneを設定してみます。
php.ini
date.timezone = "Asia/Tokyo"
$ docker container cp ./php.ini test1:/usr/local/etc/php/
コンテナを再起動してPHPの設定が変更されているのを確認してください。
$ docker container restart test1
ここまでできたら一度コンテナを削除しておいてください。
$ docker stop test1 $ docker rm test1
Dockerファイルの作成
php.iniの設定はできましたが、このままだとコンテナを削除したら再度コピーを実行しなければいけません。
一つのファイルだけならいいのですが、コピーしないといけないファイルが複数あった場合大変だし間違いが起こりそうですよね。
Dockerfileを使用すると決められた手順のコマンドをファイルに保存して実行することができます。
先ほど作成したホスト側のphp.ini
と同じディレクトリにDockerfile
を下記のように作成してください。
Dockerfile
FROM php:8.0.3-apache COPY php.ini /usr/local/etc/php/
Dockerfileを使用すると基本的にオリジナルのイメージを作るということになります。
このファイルではphp:8.0.3-apache
をベースに、独自のphp.ini
を設定した独自のイメージを作るということですね。
Dockerfileはbuildコマンドを実行することでオリジナルのイメージが生成されます。
下記コマンドはmy_php
というイメージ名で作成するということなのですが、/dockerfile/dir/
は先ほど作成したDockerfile
ファイルのあるディレクトリを指定します。
$ docker build -t my_php /dockerfile/dir/
イメージが作られたか確認してみましょう。
$ docker image ls
作成したイメージを元にコンテナを作成します。
$ docker container run --name test1 -d -p 8080:80 -v /Users/ユーザー名/htdocs:/var/www/html my_php
これでコンテナ作成時にphp.ini
が作られた状態になります。
MySQLのコンテナの作成
PHPアプリケーションはデータベースとセットで開発することがほとんどだと思います。
データベースはいろいろありますが、ここではMySQLを使えるようにしてみましょう。
PHPとは別にMySQL用のコンテナを作成しPHPと連携できるようにします。
連携する前にMySQL単独で使用してみましょう。
現時点での最新バージョンは「8.0.2」なので、イメージ名はmysql:8.0.23
にします。
MYSQL_ROOT_PASSWORD
には任意のパスワードを入力してください。
$ docker container run --name mysql_test1 -e MYSQL_ROOT_PASSWORD=password -d mysql:8.0.23
コンテナに入ってMySQLを使用できるか確認しましょう。
$ docker container exec -it mysql_test1 /bin/bash
MySQLにログイン
# mysql -u root -p
操作できるか確認してみましょう。
mysql> show databases;
問題なかったら終了
mysql> show exit;
コンテナからも抜けます。
# exit
MySQLコンテナにはその他にもオプションがあります。
MYSQL_DATABASE
を指定するとコンテナ作成時にデータベースを作成することができます。
$ docker container run --name mysql_test1 -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=test_db -d mysql:8.0.23
その他設定に書くようなオプションは引数として追加することができます。
文字コード | –character-set-server=utf8mb4 |
---|---|
照合順序 | –collation-server=utf8mb4_unicode_ci |
これを全部入れるとこんな感じです。
$ docker container run --name mysql_test1 -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=test_db -d mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
Docker Compose
一つのコンテナを作成するだけでも色々とオプションを指定しないといけなくて結構大変になってきましたね。
Docker Composeを使用すると、コマンドで入力していたのをファイルにまとめて実行することができます。
構築したPHP環境をDocker Composeで作ってみましょう。
docker
というディレクトリを作り、その中にdocker-compose.yml
というファイルを作ります。
さらに同階層にphp
デイィレクトリを作り、PHPコンテナ作成時に作ったDockerfile
とphp.ini
を入れます。
このような構造になります。
docker ├ docker-compose.yml ├ htdocs └ php ├ Dockerfile └ php.ini
Docker run で実行していたコマンドを docker-compose で書くと次のようになります。
docker-compose.yml
version: "3" services: php: container_name: php_test1 build: context: ./php ports: - 8080:80 volumes: - ./htdocs:/var/www/html restart: always
container run
と比較してもらうと大体わかるのではないかと思います。
services
直下にあるphp
はサービス名でコンテナ毎に任意の名称を指定します。
Dockerfileでコンテナを作る場合はbuild
のcontext
にDockerfileの入っているディレクトリを指定します。
restart
はコンテナが停止したときの挙動です。always
は必ず再起動する設定です。
Docker composeでcontainer run
に相当するコマンドはup
になります。
$ docker-compose -f /path/to/docker-compose.yml up -d
docker-compose.yml
ファイルのあるディレクトリをカレントディレクトリにすることで、ファイルパスのオプションを省略することができます。
$ docker-compose up -d
コンテナの停止・削除はdown
を使用します。
$ docker-compose down
コンテナの停止だけしたい場合はstop
を使用します。
$ docker-compose stop
MySQLの追加
docker-composeに先ほど作成したMySQLも追加してみましょう。
docker-compose.yml
version: "3" services: php: container_name: php_test1 build: context: ./php ports: - 8080:80 volumes: - ./htdocs:/var/www/html restart: always db: container_name: mysql_test1 image: mysql:8.0.23 volumes: - ./mysqlvol:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: test_db command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci ports: - 3306:3306
変更点はphpと同じように、データの置き場所のvolumesを設定したので、ホストにmysqlvol
ディレクトリを作成します。
up
コマンドでコンテナを作ります。
$ docker-compose up -d
簡単なファイルを作成してPHPから接続できるか確認してみましょう。
MySQLのhostはコンテナ名のmysql_test1
になります。
htdocs/index.php
<?php $dsn = 'mysql:dbname=test_db;host=mysql_test1;port=3306;'; $user = 'root'; $password = 'password'; try { $db = new PDO($dsn, $user, $password); echo '接続成功'; } catch(PDOException $e) { echo '接続失敗' . $e->getMessage(); }
http://localhost:8080
にアクセスして確認してください。
ボリュームマウント
先ほどのMySQLの設定ではPHPと同じようにバインドマウントでホストと同期したのですが、MySQLのファイルは基本的に直接操作することがないので、あまり同期させる意味はないですよね。
ただコンテナ消したときに消えてしまっては困ります。
そんなときはボリュームマウントという機能を使うことでコンテナとは別の領域にデータを置くことができます。
services
と同じ並びにvolumes
を追記します。
volumes
には任意の名前を付けましょう。
あとはvolumes
に付けた名前をdb
のvolumes
に指定します。
docker-compose.yml
version: "3" services: php: container_name: php_test1 build: context: ./php ports: - 8080:80 volumes: - ./htdocs:/var/www/html restart: always db: container_name: mysql_test1 image: mysql:8.0.23 volumes: - mysqlvol1:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: test_db command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci ports: - 3306:3306 volumes: mysqlvol1:
試しにテーブルを作ってからコンテナを再構築してDBのデータが消えていないことを確認してください。
作成したボリュームは下記で確認することができます。
$ docker volume ls
削除する場合はコンテナなどと同じようにrm
を使用します。
$ docker volume rm php_mysqlvol1
容量の確認
ボリュームに限った話ではないですが、そのままにしておくと容量が圧迫するのでこまめに削除しましょう。
下記でどのくらい容量使っているのか確認することができます。
$ docker system df -v
この記事の動画(Youtube)版はこちら!