Docker Composeでphpでmysqlにアクセスする
Docker
で作成したphp
のコンテナから別コンテナのmysql
にアクセスする方法を紹介します。
Docker ComposeでNginxとphpを連携するで作成した環境に対して修正を行っていきます。
mysqlの設定
mysql
のコンテナを作成します。
db
というサービス名で作成します。このサービス名は後ほど使用するため、覚えておいてください。
volumes
でmysql
のデータをマウントすることにより、コンテナを停止してもデータベースの内容を永続化しています。
また、他のコンテナと同様に、ホスト側で記載した設定ファイルをコンテナ側で読み込むようにしています。
ルートパスワードの設定とdocker_db
という名前でデータベースも作成しています。
また、app
コンテナ(php
)からdb
コンテナを参照するため、app
コンテナの設定のdepends_on
にdb
を追加します。
docker-compose.yml
version: '3'
services:
web:
image: nginx
depends_on:
- app
ports:
- "8080:80"
volumes:
- ./docker/web/default.conf:/etc/nginx/conf.d/default.conf
- .:/var/www/html
app:
image: php:7-fpm
depends_on:
- db
volumes:
- ./docker/app/php.ini:/usr/local/etc/php/php.ini
- .:/var/www/html
db:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: docker_db
MYSQL_USER: docker_user
MYSQL_PASSWORD: docker_pass
ports:
- "3306:3306"
volumes:
- ./docker/db/data:/var/lib/mysql
- ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
フォルダ構成は以下になります。(my.cnfのファイルの中身は空で問題ありません)
- カレントディレクトリ
- docker
- web
- default.conf
- app
- php.ini
- db ←追加
- data ←追加
- my.cnf ←追加
- web
- docker-compose.yml
- index.html
- info.php
- docker
接続確認
php
で接続確認を行うためのファイルを作成します。
connect.php
<?php
try {
// host=XXXの部分のXXXにはmysqlのサービス名を指定します
$dsn = 'mysql:host=db;dbname=docker_db;';
$db = new PDO($dsn, 'docker_user', 'docker_pass');
$sql = 'SELECT version();';
$stmt = $db->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
} catch (PDOException $e) {
echo $e->getMessage();
exit;
}
コンテナを実行し、localhost:8080/connect.php
にアクセスすると「could not find driver」のエラーが発生します。
php
にmysql
の接続に必要なモジュールがインストールされていないため、必要なモジュールをインストールするようにphp
のイメージを修正します。
phpイメージの作成
ベースのイメージは今まで使用していたphp:7-fpm
で、さらにmysql
の接続に必要なモジュールをインストールするように、DockerFile
を作成します。
- カレントディレクトリ
- docker
- web
- default.conf
- app
- php.ini
- DockerFile ←追加
- db
- data
- my.cnf
- web
- docker-compose.yml
- index.html
- info.php
- connect.php
- docker
以下の設定はphp:7-fpm
のイメージをベースに、パッケージをアップデートして最新にしたあと、docker-php-ext-install
でpdo_mysql
のモジュールをインストールしています。
DockerFile
FROM php:7-fpm
RUN apt-get update \
&& docker-php-ext-install pdo_mysql
このDockerFile
で作成したイメージを使用するように、docker-compose.yml
を修正します。
docker-compose.yml
app:
image: php:7-fpm
depends_on:
- db
build: ./docker/app
volumes:
- ./docker/app/php.ini:/usr/local/etc/php/php.ini
- .:/var/www/html
環境構築の最中はデータベースの設定情報などを初期化したいため、mysql
のコンテナを再起動するときは以下のコマンドで永続化したフォルダを削除してから起動するようにします。
$ sudo rm -rf docker/db/data
また、コンテナを起動直後にデータベースにアクセスすると以下のエラーになることがあります。
SQLSTATE[HY000] [2002] Connection refused
エラーが表示された場合は少し(30秒ほど)待ってから再度確認してみてください。
再度実行すると今度は以下のエラーが表示されます。
SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client
これはDocker
の設定の問題というわけではなく、MySQL
のバージョンが8
以上の場合に、デフォルトの認証方法が変更されたことによるエラーです。
従来の認証方法にするため、MySQL
の設定ファイルに以下を記載します。
my.conf
[mysqld]
default_authentication_plugin=mysql_native_password
再度アクセスするとSQL
が実行され、MySQL
への接続ができていることが確認できます。
phpmyadmin
を導入する方法はDocker Composeでphpmyadminを導入するで紹介します。