Docker初心者がCakePHP3の開発環境構築時イメージ作成を考える

# はじめに
CakePHPを体系的に学習するついでに、Dockerで開発環境を構築して、どのようコンテナを作るのがいいのかをまとめようと思います。
個人的にこれがいいと思う開発環境構築方法が書ければ良いかなと思います。
ベースイメージを決めてそれに加えて、必要なものをインストールする形になると思います。
また、コンテナを複数使用する場合が考えられるため、その際にはdocker composeをしようします。

# 開発環境の内容
今回は以下の条件でシンプルなWEBアプリ開発環境を作成しようと思います。  

- PHP7.2.5
- CakePHP3
- Apache 
- MySQL

# コンテナの種類
- CakePHP3＆APache(fpmではなくモジュール版PHPを使用する)
- MySQL

# CakePHP3用イメージ
## 使用するイメージの選ぶ基準
PHPの公式イメージは多くのイメージが存在する。PHPのバージョンや、同梱されているwebサーバなど、様々な種類のイメージがあります。
今回の開発環境を作るとしてもかなりの数があり絞れない。
イメージの選び方として、参考になるQiita記事がありました。 
[Dockerベースイメージの特徴と比較・選び方
](https://qiita.com/mumoshu/items/edd76958ea170a6b8e3d)

軽く書くと以下の内容が記載されていた。  

- イメージが誰がどのように作成したのか
- セキュリティ的に大丈夫か
- イメージのサイズ
- アプリの実行環境を整えるまでに必要な手数

確かに納得できる内容でした。普段「アプリの実行環境を整えるまでに必要な手数」だけ気にしていたと思います。
上記内容を参考にすると以下に絞れる。
1. PHPまたはOSの公式イメージ
2. 軽量なイメージ

今回はシンプルなWEBアプリであり元々手数はかからないため「アプリの実行環境を整えるまでに必要な手数」の観点はあまり気にしなくて良さそう。

## 軽量なイメージAlpine Linux
軽量なイメージを選ぶことのメリットとしては、以下になりま//す。

- デプロイが早くなる
- 起動が早くなる

アプリケーションなどの性能には基本的に軽量化とは関係ありません。
他のイメージよりも圧倒的なイメージがAlpine Linuxです。
圧倒的に軽いことがわかるQiitaの記事がありました。
[Alpine Linux で Docker イメージを劇的に小さくする
](https://qiita.com/asakaguchi/items/484ba262965ef3823f61)
そのためAlpine Linuxを選択する方が良いでしょう。

## Alpineイメージを使う
Alpine Linuxがベースになったイメージは多くありましたが、
自分で使いこなせそうなのが、Alpineだけのイメージでした。PHP公式のイメージやApache公式のイメージを試しましが、
使いこなせず、どちらも自分にはわかりずらかった。
そのため結局、PHPなど何もインストールされていない[Alpineイメージ](https://hub.docker.com/layers/alpine/library/alpine/3.10/images/sha256-33158d51a7a549207e508a42bf46493f23e1e99fbc011eb3f3742e8b349a2be9?context=explore)
を選択しました。
ここにPHPやAPacheをインストールしていきます。
## プロジェクトのディレクトリ構造
```
cake3app
├── docker
│   ├── Dockerfile
│   └── app // php.iniとhttpd.confが格納されている
├── docker-compose.yml
└── sample // CakePHPのソース
    ├── README.md
    ├── bin
    ├── composer.json
    ├── composer.lock
    ├── config
    ├── index.php
    ├── logs
    ├── phpunit.xml.dist
    ├── plugins
    ├── src
    ├── tests
    ├── tmp
    ├── vendor
    └── webroot
```

## DockerFile
PHPと必要なCakeに必要なライブラリとComposerをインストールして、
Cakeのソースをコピーして、composer installコマンド実行する処理になります。  

```dockerfile:DockerFile
FROM alpine:3.10

## Packageインストール intlはCakePHPで必須のライブラリらしいエラーが表示される。php.iniでも有効にしておく必要がある
RUN apk add --update --no-cache php7 php7-pdo_mysql php7-openssl php7-curl php7-json php7-mbstring \
    php7-apache2 php7-pdo_odbc php7-pdo_mysql php7-gd php7-pecl-apcu php7-mysqli php7-fpm php7-intl php7-phar php7-dom php7-xml php7-simplexml php7-tokenizer php7-xmlwriter php7-session apache2

## composerをインストール
COPY --from=composer /usr/bin/composer /usr/bin/composer
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /usr/bin/composer
ENV PATH $PATH:/composer/vendor/bin

COPY ./sample /var/www/html/sample/
WORKDIR /var/www/html/sample/
RUN composer install --no-interaction
CMD ["httpd", "-D", "FOREGROUND"]
```

## docker compose
```dockerfile:docker-compose.yml
version: "3"
services:
  php:
    build:
     context: .
     dockerfile: ./docker/Dockerfile
    volumes:
      - ./sample:/var/www/html/sample
      - ./docker/app/php.ini:/usr/local/lib/php.ini
      - ./docker/app/httpd.conf:/etc/apache2/httpd.conf
    tty: true
    ports:
     - 80:80
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: cake_php
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
      TZ: 'Asia/Tokyo'
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --explicit_defaults_for_timestamp=1
    ports:
      - 3306:3306
```
コンテナ  

- php
  - Apache Webサーバ
  - CakePHP
- mysql

これでローカル環境でWebサーバとアプリケーションとDBの一式の開発環境が構築できます。

## まとめ
たくさんのイメージが存在するが、結局Alpineのみのイメージをベースにしえ必要なものをインストールする方が、使いやすく、余計なものもないため軽量を維持できるというメリットがあるなと思いました。
あと世の中的にnginxをしようしている人が多い印象ですが、レンタルサーバなどの複数のプロジェクトを同一サーバにデプロイしない限りApacheの方がメリットが大きいらしいです。
1コンテナ1プロセスで運用するのがベターということですが、ApacheでPHPを実行する場合は、同一プロセスでPHPが動くので、それも守っている。
結局PHPはApacheが一番相性いいのではと思いました。
Apacheの設定ファイルの構造はちゃんと理解していないので、どこかで勉強しないとですね。
意外とAlpineで構築したという記事が少なく、CentOSかUbuntuを使っている人が多かったのが気になりました。