DockerベースPHP開発環境（on Windows）

# 経緯

## 状況

- WindowsでのPHPのWebアプリケーション開発
- 一つの端末で、複数PHPバージョンの複数アプリケーションを保守している
    - PHP5.3とか古いバージョン保守や、設計が古いアプリケーションの保守を含む

## 課題と検討

- 同一開発（実行）環境を（システム的に）担保しつつ容易に構築できるようにしたい
- 実行環境：PHPバージョン管理（XXXenv）＋composerではうまくいかない
    - php.iniが（アプリケーションごとでなく）バージョンごとの単位で存在したり
    - windowsバイナリでライブラリを（アプリケーションごとでなく）バージョンごとにインストールしないといけなかったり
- PHPバージョン管理：Windowsで既存PHPバージョンマネージャ使いにくい問題
    - これ、皆さま方本当にどうしているんですか？Windowsなんて使っていないんでしょうか？
- 仕方ない、全部Dockerでやっていこう

# Dockerでやってみる

| Software   | Version    |
|:----------:|:----------:|
| Docker Desktop | 2.0.0.3 |
| PHPStorm | 2018.3.5 |

## サンプル構成

- ディレクトリ構成

```
/
├ public/
│    └ index.php
├ src/
│    └ SampleClass.php
├ tests/
│    └ SampleClassTest.php
├ vendor/
├ .dockerignore
├ composer.json
├ docker-compose.yml
├ Dockerfile
├ phpunit.xml
└ xdebug.ini
```

- Dockerfile

```dockerfile
FROM php:7.2-cli-stretch

RUN pecl install xdebug-2.6.0 \
    && docker-php-ext-enable xdebug

RUN apt-get update && apt-get upgrade -y \
    && apt-get install -y --no-install-recommends git \
    && apt-get clean && rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/*

RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
    && php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
    && php composer-setup.php \
    && php -r "unlink('composer-setup.php');" \
    && mv composer.phar /usr/local/bin/composer

COPY ./ /var/www
WORKDIR /var/www
RUN composer install
```

- docker-compose.yml

```docker
version: '3'

services:
  sample:
    build: .
    image: sample
    working_dir: /var/www
    command: php -S 0.0.0.0:8080 -t public
    environment:
      docker: "true"
    ports:
      - 80:8080
    volumes:
      - ./:/var/www
      - ./xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

  cli:
    build: .
    image: sample
    working_dir: /var/www
    environment:
      docker: "true"
    volumes:
      - ./:/var/www
      - ./xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
```

## composerコマンド実行

- ターミナルで

```bash
$ docker-compose run cli composer install
$ docker-compose run cli composer require XXX/XXXX
```

- PHPStormで
    - composerコマンド実行におけるRemote CLI Interpreterは非対応

## 実行環境構築

- ターミナルで

```bash
$ docker-compose up -d sample
$ docker-compose down
```

- composerで
    - scriptsに"start","stop"として上のコマンドを追加
    - "build"とか"push"とかもお好みで

```bash
$ composer start
$ composer stop
```

- PHPStormで

```
Run/Debug Configurations: "Docker" -> "Docker-compose"
  compose file(s): 指定
  Service(s): sample
```

## 単体テスト

- ターミナルで

```bash
$ docker-compose run cli vendor/bin/phpunit --configuration phpunit.xml tests
```

- composerで
    - scriptsに"test"として上のコマンドを追加

```bash
$ composer test
```

- PHPStormで

```
Languages & Frameworks > PHP
  CLI Interpreters: (追加+追加したもので設定)
    Remote: Docker compose
      Configuration file(s): .\docker-compose.yml
      Service: cli
  Path mappings:  (自動で読み込まれるので、通常設定不要なはず)

Languages & Frameworks > PHP > TestFrameworks: (追加)
  Interpreter: (追加したもの)
  (その他設定は自動で読み込まれるので、通常設定不要なはず)

Run/Debug Configurations: "PHPUnit"
  Test scope: Directory
  Directory: (testsディレクトリへのパス)
```

## いまいちなところ

- ローカルでcomposer実行しないルールが必要
  - WindowsのPHPバージョン管理システムがあれば良い

# まとめ

- 本記事の内容はどうでもよく、皆さまどうしているのか知りたいというのが本当の趣旨です