Edited at

DockerでPHP5-Alpineの開発環境(MySQL、Redis)を作る


はじめに

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

GitHub上に変更したファイルを載せています。


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の設定も追加しています。


app/Dockerfile

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.ini自体は、コンテナのデフォルト設定を使っています。

date.timezoneの設定をする必要がありましたので、php.iniを用意するのではなく、xdebug.iniに追記して、設定ファイルを1つにしています。


xdebug.ini

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は、共有ファイルとしてコンテナにマウントして利用します。


docker-compose.yml

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 側の設定は、以下の記事を参考にさせていただきまして、デバッグ環境を手に入れることができました。


launch.json

        {

"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のデバッグモードを利用できるようになりました。

index_php_—_nginx-http2-php-mysql.png

Step_6_nginx___PHP5___MySQL.png


補足

xdebugの設定を見ると、9000ポートは使用しているから90001にするとかって設定をみます。php-fpmのポートが9000で、Xdebugの9000とかぶるという考えのように思えます。

私も勘違いをしていたのですが、Xdebugはクライアントでデバッガ(Vscode)がサーバとなります。

図にすると以下のような感じです。

php-docker-xdebug.png

簡単に説明すると。。。


  1. ブラウザで127.0.0.1(:80)を開くとNginx(web)に接続します。

  2. Nginxは、index.phpのアクセスということで、PHP-FPMの9000ポートにPHPの処理を依頼します。

  3. PHP-FPMは、PHPの処理をするのですが、Xdebugの設定がある場合は、PHPの処理を「xdebug.remote_host:xdebug.remote_port」に送信します。

  4. デバッガ(VS Code)が127.0.0.1:9000ポートで待ち受けしており、PHP-FPMからのPHPの処理情報を受け取ります。


PHP Redisの導入

Redisも使いたいので導入していきます。

こちらもxdbugと同様にPeclで導入するのが定石のようです。

以下のDockerFileのXdebugのところに redisを追加します。


app/DockerFile

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サーバを追加します。


docker-compose.yml

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」の環境変数で指定をしています。


.env

・・・

# REDIS関係
REDIS_PORT=6379
REDIS_PASSWORD=password


PHP上のRedisの動作確認は、phpredisの使い方まとめを参考にさせていただきました。

テスト用にindex.phpにRedisのテストコードを追記します。

しれっと「REDIS_HOST」という環境変数がありますが、こちらはdocker-composeでappコンテナで指定ししています。


data/html/index.php

        $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>';


以下のように動作確認ができました。

Step_7_nginx___PHP5___MySQL___xdebug___redis.png


まとめ

PHPの開発環境が何度でも再現可能な状態にすることができました。

今後のPHPの開発で活用していきたいですね。

ちなみに、あとメールのテスト環境がほしいので作っていきます。

メール環境を構築しました!