はじめに
Dockerの復習がてら、PHPの開発環境を構築してみた。
システム構成
- nginx
- php-fpm
- php5/php7
- mysql
- redis
世の中、PHP5のサポートが切れるのでPHP7へ移行中です。そのため、PHP5の開発環境が必要になるのです。
PHP5だけの対応部分を書いておきますので、それを無視すればPHP7でも動作します。
nginx + php7 + mysql (+http2)
リクルートの山田さんの記事が、ステップ・バイ・ステップで書かれていて、Dockerの理解・復習にはかどります。
ありがとうございます!
docker-compose による nginx + HTTP/2 + PHP-FPM7 + MySQL 環境の構築方法
php5-alpine対応
Docker HubのPHPのリポジトリからPHP5+alpineのイメージを探して書き換えます。
FROM php:5-fpm-alpine
RUN docker-php-ext-install pdo_mysql mysqli mbstring
xdbug対応
デバッガがあるかないかは、使える装備が竹槍なのか戦車なのかぐらい効率・威力が違います。
作成したサンプルは以下になります。
https://github.com/idani/nginx-http2-php-mysql/tree/master/step6-php5-xdebug
以下の記事を参考にDockerFileを書き換えていきます。
こちらの記事からリンクされているGithub上の設定ファイルの方が、かなり参考になります。
一読されると良いかと思います。
php-alpineコンテナにxdebugをインストールする時にハマったメモ
さて、PHP5向けには、最新のXdebugは対応していません。
xdebugのリリースノートを確認すると、2.6からPHP5をサポートしないということです。このためxdebugの2.5.5を利用します。
※PHP7の方は、2.5.5を外してください。
また、Xdebugを導入することで、時刻表示の警告が表示されるようになりました。
このためTimezoneの設定も追加しています。
FROM php:5-fpm-alpine
# timezone
ARG TZ=Asia/Tokyo
# Composer install
RUN set -eux && \
apk add --update --no-cache --virtual=.build-dependencies \
autoconf \
gcc \
g++ \
make \
tzdata && \
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
echo ${TZ} > /etc/timezone && \
pecl install xdebug-2.5.5 && \
apk del .build-dependencies && \
docker-php-ext-install pdo_mysql mysqli mbstring && \
docker-php-ext-enable xdebug
また、xdebug用の追加設定は、「xdebug.ini」として、別途作成して、追加設定という感じで読み込むようにしています。
- [PHP] Xdebug のリモートデバッグ、理解していますか?を参考にさせていただきました。
補足ですが、php.ini自体は、コンテナのデフォルト設定を使っています。
date.timezoneの設定をする必要がありましたので、php.iniを用意するのではなく、xdebug.iniに追記して、設定ファイルを1つにしています。
date.timezone = "Asia/Tokyo"
xdebug.remote_enable=1
xdebug.remote_autostart=1
xdebug.remote_port=9000
xdebug.remote_host="host.docker.internal"
xdebug.remote_connect_back = 0
; xdebug.remote_log=/tmp/xdebug.log
このxdebug.iniは、共有ファイルとしてコンテナにマウントして利用します。
version: '3'
services:
web:
image: nginx:1.13.5-alpine
ports:
- "80:80"
depends_on:
- app
volumes:
- ./web/default.conf:/etc/nginx/conf.d/default.conf
- ./data/html:/var/www/html
app:
build: ./app
env_file: .env
environment:
DATABASE_HOST: db
depends_on:
- db
volumes:
- ./data/html:/var/www/html
- ./xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini
db:
image: mysql:5.7.19
env_file: .env
ports:
- "3306:3306"
volumes:
- db-data:/var/lib/mysql
- ./db/initial.sql:/docker-entrypoint-initdb.d/initial.sql
volumes:
db-data:
VS code 側の設定は、以下の記事を参考にさせていただきまして、デバッグ環境を手に入れることができました。
{
"name": "Listen for XDebug step6",
"type": "php",
"request": "launch",
"port": 9000,
"pathMappings": {
// {docker上のdocument root}:{ローカルのdocument root}
"/var/www/html":"${workspaceRoot}/step6-php5-xdebug/data/html"
}
},
launch.jsonの全体像は、Gitのサンプルで確認をしてください。
これで以下のようにvscodeのデバッグモードを利用できるようになりました。
補足
xdebugの設定を見ると、9000ポートは使用しているから90001にするとかって設定をみます。php-fpmのポートが9000で、Xdebugの9000とかぶるという考えのように思えます。
私も勘違いをしていたのですが、Xdebugはクライアントでデバッガ(Vscode)がサーバとなります。
図にすると以下のような感じです。
簡単に説明すると。。。
- ブラウザで127.0.0.1(:80)を開くとNginx(web)に接続します。
- Nginxは、index.phpのアクセスということで、PHP-FPMの9000ポートにPHPの処理を依頼します。
- PHP-FPMは、PHPの処理をするのですが、Xdebugの設定がある場合は、PHPの処理を「xdebug.remote_host:xdebug.remote_port」に送信します。
- デバッガ(VS Code)が127.0.0.1:9000ポートで待ち受けしており、PHP-FPMからのPHPの処理情報を受け取ります。
PHP Redisの導入
Redisも使いたいので導入していきます。
こちらもxdbugと同様にPeclで導入するのが定石のようです。
以下のDockerFileのXdebugのところに redisを追加します。
FROM php:5-fpm-alpine
# timezone
ARG TZ=Asia/Tokyo
# Composer install
RUN set -eux && \
apk add --update --no-cache --virtual=.build-dependencies \
autoconf \
gcc \
g++ \
make \
tzdata && \
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
echo ${TZ} > /etc/timezone && \
pecl install redis xdebug-2.5.5 && \
apk del .build-dependencies && \
docker-php-ext-install pdo_mysql mysqli mbstring && \
docker-php-ext-enable redis xdebug
次に、docker-copose.yml にRedisサーバを追加します。
version: '3'
services:
web:
image: nginx:1.13.5-alpine
ports:
- "80:80"
depends_on:
- app
volumes:
- ./web/default.conf:/etc/nginx/conf.d/default.conf
- ./data/html:/var/www/html
app:
build: ./app
env_file: .env
environment:
DATABASE_HOST: db
REDIS_HOST: redis
depends_on:
- db
- redis
volumes:
- ./data/html:/var/www/html
- ./app/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini
db:
image: mysql:5.7.19
env_file: .env
ports:
- "3306:3306"
volumes:
- db-data:/var/lib/mysql
- ./db/initial.sql:/docker-entrypoint-initdb.d/initial.sql
redis:
image: redis:alpine3.9
command: redis-server --requirepass ${REDIS_PASSWORD}
ports:
- "${REDIS_PORT}:${REDIS_PORT}"
volumes:
db-data:
Redis用のパスワード(REDIS_PASSWORD)とポート(REDIS_PORT)は、「.env」の環境変数で指定をしています。
・・・
# REDIS関係
REDIS_PORT=6379
REDIS_PASSWORD=password
PHP上のRedisの動作確認は、phpredisの使い方まとめを参考にさせていただきました。
テスト用にindex.phpにRedisのテストコードを追記します。
しれっと「REDIS_HOST」という環境変数がありますが、こちらはdocker-composeでappコンテナで指定ししています。
$redis = new Redis();
$redis->connect($_ENV['REDIS_HOST'], $_ENV['REDIS_PORT']);
$redis->auth($_ENV['REDIS_PASSWORD']);
echo '<pre class="log">';
echo 'Redis接続' . PHP_EOL;
echo $redis->ping() . PHP_EOL;
// string_keyというkeyにhugaという値をセット
$redis->set('string_key', 'huga');
// 値を取得する
$value = $redis->get('string_key');
// 表示
echo $value . PHP_EOL; // huga
// lPushは先頭、rPushは末尾に値をpush
$redis->rPush('list_key', 'a');
$redis->rPush('list_key', 'b');
$redis->lPush('list_key', 'c');
$redis->lPush('list_key', 'd');
// 値をすべて取得する -1はすべて
$value = $redis->lRange('list_key', 0, -1);
// 表示
var_dump($value);
echo '</pre>';
以下のように動作確認ができました。
まとめ
PHPの開発環境が何度でも再現可能な状態にすることができました。
今後のPHPの開発で活用していきたいですね。
ちなみに、あとメールのテスト環境がほしいので作っていきます。
メール環境を構築しました!