はじめに
この記事では、Docker のネットワーク機能を利用して、PHP コンテナから MySQL コンテナへ通信できるようにする手順について記載します。
ネットワークへの理解促進の一環で行っています。
開発環境
開発環境は以下の通りです。
- Windows 11
- Docker Engine 26.1.1
- MySQL 8.4.0
- PHP 8.3
ネットワークの作成 docker network create
docker network create
でネットワークを作成します。
docker network create my-network
docker network ls
で作成したネットワークを確認します。
docker network ls
作成した my-network
のほかに bridge
、host
、none
というネットワークも存在します。これらは、Docker が自動で作成するデフォルトのネットワークです。この中の bridge
は、コンテナ起動時にネットワークを指定しなかった場合にコンテナが接続するデフォルトネットワークです。デフォルトブリッジネットワークと呼ばれます。
デフォルトブリッジネットワークに対し、今回のように自分で作成したネットワークをユーザー定義ブリッジネットワークと呼びます。コンテナ間通信では、ユーザー定義ブリッジネットワークを利用することが推奨されています。
ping コマンドが使える PHP イメージをビルドする
PHP コンテナから MySQL コンテナへ通信ができるようにする過程で、ネットワークの疎通確認を行いたいので、ping コマンドが使える PHP イメージをビルドします。
Dockerfile を作成する
まずは、Dockerfile を作成します。
PHP イメージはタグが 8.3 のイメージを利用します。
ping コマンドは inputils-ping
というパッケージを利用します。
FROM php:8.3
RUN apt-get update
RUN apt-get install -y iputils-ping
イメージをビルドする
先ほど作成した Dockerfile を利用し、docker image build
でイメージをビルドします。
docker image build --tag my-php:ping .
イメージが作成できたか確認します。
docker image ls my-php
動作確認
イメージが作成できたので、コンテナを作成して、ping コマンドが利用できるか確認します。まだ MySQL コンテナは作成していないので、現時点では localhost と疎通確認推します。
docker container run my-php:ping ping -c 3 -t 1 localhost
コンテナ起動時にネットワークに接続する docker container run --network
MySQL コンテナと PHP コンテナを起動し、作成した my-network
に接続して通信できるようにします。
ネットワークへの接続は docker container run
コマンドの --network
オプションを指定します。
MySQL コンテナ起動時にネットワークに接続する
まずは MySQL コンテナを起動して、ネットワークに接続します。
docker container run `
--name db `
--rm `
--detach `
--env MYSQL_ROOT_PASSWORD=password `
--env MYSQL_DATABASE=sample `
--publish 3306:3306 `
--network my-network `
mysql:8.4.0
コンテナが起動したか確認します。
docker container ls
MySQL サーバーに接続します。
mysql --host=127.0.0.1 --port=3306 --user=root --password=password sample
動作確認のため、users テーブルを作成し、Wyatt と Billy を追加します。
create table users (id int, name varchar(32));
insert into users (id, name) values (1, 'Wyatt');
insert into users (id, name) values (2, 'Billy');
作成できたか確認します。
select * from users;
PHP コンテナから MySQL コンテナに疎通できるか確認する
疎通確認のため、先ほどビルドした my-php:ping
イメージを使い、起動した db コンテナに ping コマンドを実行します。
docker container run --network my-network my-php:ping ping -c 3 -t 1 db
PHP コンテナで MySQL サーバーに接続するためにイメージを拡張する
PHP で MySQL サーバーに接続するためには PDO_MYSQL
という拡張モジュール(ドライバー)が必要になります。
また、インストールには、公式の PHP イメージが用意してくれている docker-php-ext-install
コマンドを利用します。
Dockerfile に PDO_MYSQL
をインストールするための RUN インストラクションを追加します。
FROM php:8.3
RUN apt-get update
RUN apt-get install -y iputils-ping
RUN docker-php-ext-install pdo_mysql
更新した Dockerfile をもとにイメージをビルドします。
今回はタグを pdo_mysql
とします。
docker image build --tag my-php:pdo_mysql .
イメージが作成できたか確認します。
docker image ls my-php
PHP コンテナで MySQL サーバーに接続するコードを実装する
PHP イメージの準備ができたので、PHP コンテナで実行する PHP ファイル main.php
を作成します。
ファイル内では、MySQL に接続し、users テーブルの中身を出力する処理を実装します。
<?php
// Connect to DB
$dsn = 'mysql:host=db;port=3306;dbname=sample';
$username = 'root';
$password = 'password';
$pdo = new PDO($dsn, $username, $password);
// Echo user table
$statement = $pdo->query('select * from users');
$statement->execute();
while ($row = $statement->fetch()) {
echo '- id: ' . $row['id'] . ', name: ' . $row['name'] . PHP_EOL;
}
// Disconnect
$pdo = null;
PHP コンテナを起動して MySQL コンテナへ通信する
PHP コンテナ起動時に先ほど作成した main.php
を PHP コンテナで実行し、 PHP コンテナから MySQL コンテナへ通信します。
docker container run `
--rm `
--mount type=bind,source="$(pwd)",target=/my-work `
--network my-network `
my-php:pdo_mysql `
php /my-work/main.php
-
--mount type=bind,source="$(pwd)",target=/my-work
: ホストマシンで作成したmain.php
をコンテナで実行したいので、"$(pwd)"
(作業ディレクトリの絶対パス)を/my-work
にバインドマウントします -
--network my-network
: MySQL コンテナと同じネットワークに接続します -
php /my-work/main.php
: バインドマウントの"$(pwd)"
と同じディレクトリで実行
ホストマシンで作成した PHP ファイルをコンテナで実行し、MySQL コンテナのデータを取得できました!