Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

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の開発で活用していきたいですね。

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

idani
井谷(いだに)と申します。 前職では、cakePHPとjQueryとVue.jsを使って、メール配信、SMS配信、セミナー募集システム、かんたんな決済処理、アフィリエイトシステムなどを開発していました。 使える言語は、C、C++、Perl、C#、PHP、JSになります。 昔々、Gentoo Linuxの翻訳作業をしていました。
https://hirotae.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away