CakePHP3 dockerを用いて圧倒的環境構築

dockerを用いて一瞬でCakePHP環境を構築したいと思います。

今回はこちらの記事 (http://qiita.com/nmatayoshi/items/e7f34e1e220264131934) を参考にさせていただきました。
ありがとうございます！

## 動作環境

* OSX EI Capitan 10.11.6
* Docker version 17.03.0-ce
* mysql  Ver 14.14 Distrib 5.7.17(ローカル)

## dockerを使って構築

dockerがインストールされている、かつmac環境前提で進めていきます。
win環境の方はすみません、参考程度にしてください。

一つずつコンテナを立てていってもいいんですが、面倒臭いし順番を間違えたらいろいろとトラブルの原因になります。
今回はGithubで公開されているDockerfileを元に書いたdocker-composeを使ってコンテナを立てます。
php:7-fpm-alpineイメージを使用します。

公開先はこちら(https://github.com/matayoshi/docker_cakephp3_tutorial)

まずディレクトリをとってきます。
git clone先はhomeディレクトリです。

```
$ cd ~ && git clone https://github.com/matayoshi/docker_cakephp3_tutorial.git

$ cd docker_cakephp3_tutorial

$ ls
LICENSE			README.md		data			docker-compose.yml
```
cloneしたディレクトリが上記のようになっていればおｋです。

では、docker-composeコマンドで作成していきます。

```
$ docker-compose build
Building mysql
Step 1/3 : FROM mysql:5.7
 ---> c73c7527c03a
Step 2/3 : RUN usermod -u 1000 mysql
 ---> Using cache
 ---> 248468bce96e
Step 3/3 : RUN mkdir -p /var/run/mysqld &&   chmod -R 777 /var/run/mysqld
 ---> Using cache
 ---> 2962003ec25e
Successfully built 2962003ec25e
Building phpfpm
Step 1/3 : FROM php:7-fpm-alpine
 ---> 360b66277c6e
Step 2/3 : RUN set -x &&   apk add --no-cache icu-libs &&   apk add --no-cache --virtual build-dependencies icu-dev &&   NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) &&   docker-php-ext-install -j${NPROC} intl &&   docker-php-ext-install -j${NPROC} pdo_mysql &&   apk del --no-cache --purge build-dependencies &&   rm -rf /tmp/pear
 ---> Using cache
 ---> 8deed7dc2874
Step 3/3 : RUN set -x &&   deluser www-data &&   addgroup -g 50 -S www-data &&   adduser -u 1000 -D -S -G www-data www-data
 ---> Using cache
 ---> 5615ee9a6902
Successfully built 5615ee9a6902
nginx uses an image, skipping
```
buildした際nginxのイメージがすでに存在していたのでskipされたようです。
mysql、phpfpm、nginxの三つがちゃんとbuildされているか確認してください。

次にコンテナを作成します。

```
$ docker-compose create
Creating dockercakephp3tutorial_mysql_1
Creating dockercakephp3tutorial_phpfpm_1
Creating dockercakephp3tutorial_nginx_1
```
ディレクトリの名前でコンテナが作成されました。本当に作成されているか念のため確認。

```
$ docker ps -a
CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS                      PORTS                    NAMES
6f355b293deb        nginx:mainline-alpine           "nginx -g 'daemon ..."   5 minutes ago       Created                                              dockercakephp3tutorial_nginx_1
22610333759e        dockercakephp3tutorial_phpfpm   "docker-php-entryp..."   5 minutes ago       Created                                              dockercakephp3tutorial_phpfpm_1
897f62e5d8f3        dockercakephp3tutorial_mysql    "docker-entrypoint..."   5 minutes ago       Created                                              dockercakephp3tutorial_mysql_1
```

問題なさそうですね〜。
では、コンテナのサービスを起動します。
nginxでサーバーを同時に起動するので、デタッチドで動かします。

```
$ docker-compose up -d
Creating network "dockercakephp3tutorial_default" with the default driver
Starting dockercakephp3tutorial_mysql_1
Starting dockercakephp3tutorial_phpfpm_1
Starting dockercakephp3tutorial_nginx_1
```

問題なくいけてます。

※ もし以前に別のコンテナを作成していて、その時にnginxのコンテナがあった場合、ポートが被ってエラーになることがあります。その場合はコンテナを停止させて、上記を再実行してください。


では、CakePHPのcomposerをphpfpmコンテナに入ってインストールします。
同時にプロジェクトも作成しましょう。

```
$ docker exec -it docker_cakephp3_tutorial_phpfpm_1 /bin/sh
/var/www/html # curl -s https://getcomposer.org/installer | php
All settings correct for using Composer
Downloading...
   
Composer (version 1.5.1) successfully installed to: /var/www/html/composer.phar
Use it: php composer.phar


/var/www/html # php composer.phar create-project --prefer-dist cakephp/app bookmarker
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Installing cakephp/app (3.5.0)
  - Installing cakephp/app (3.5.0): Downloading (100%)         
Created project in practice
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 39 installs, 0 updates, 0 removals
  - Installing cakephp/plugin-installer (1.0.0): Downloading (100%)         
  - Installing aura/intl (3.0.0): Downloading (100%)         
  - Installing mobiledetect/mobiledetectlib (2.8.25): Downloading (100%)         
  - Installing psr/http-message (1.0.1): Downloading (100%)         
  - Installing zendframework/zend-diactoros (1.5.0): Downloading (100%)         
  - Installing psr/log (1.0.2): Downloading (100%)         
  - Installing cakephp/chronos (1.1.2): Downloading (100%)         
  - Installing cakephp/cakephp (3.5.0): Downloading (100%)         
  - Installing symfony/polyfill-mbstring (v1.5.0): Downloading (100%)         
  - Installing symfony/yaml (v3.3.6): Downloading (100%)         
  - Installing symfony/debug (v3.3.6): Downloading (100%)         
  - Installing symfony/console (v3.3.6): Downloading (100%)         
  - Installing symfony/filesystem (v3.3.6): Downloading (100%)         
  - Installing symfony/config (v3.3.6): Downloading (100%)         
  - Installing robmorgan/phinx (v0.8.1): Downloading (100%)         
  - Installing cakephp/migrations (1.7.1): Downloading (100%)         
  - Installing m1/env (2.1.0): Downloading (100%)         
  - Installing josegonzalez/dotenv (2.1.0): Downloading (100%)         
  - Installing jakub-onderka/php-console-color (0.1): Downloading (100%)         
  - Installing jakub-onderka/php-console-highlighter (v0.3.2): Downloading (100%)         
  - Installing dnoegel/php-xdg-base-dir (0.1): Downloading (100%)         
  - Installing nikic/php-parser (v3.1.0): Downloading (100%)         
  - Installing symfony/var-dumper (v3.3.6): Downloading (100%)         
  - Installing psy/psysh (v0.8.11): Downloading (100%)         
  - Installing jdorn/sql-formatter (v1.2.17): Downloading (100%)         
  - Installing symfony/process (v3.3.6): Downloading (100%)         
  - Installing symfony/finder (v3.3.6): Downloading (100%)         
  - Installing seld/phar-utils (1.0.1): Downloading (100%)         
  - Installing seld/jsonlint (1.6.1): Downloading (100%)         
  - Installing seld/cli-prompt (1.0.3): Downloading (100%)         
  - Installing justinrainbow/json-schema (5.2.1): Downloading (100%)         
  - Installing composer/spdx-licenses (1.1.6): Downloading (100%)         
  - Installing composer/semver (1.4.2): Downloading (100%)         
  - Installing composer/ca-bundle (1.0.7): Downloading (100%)         
  - Installing composer/composer (1.5.1): Downloading (100%)         
  - Installing cakephp/debug_kit (3.11.0): Downloading (100%)         
  - Installing cakephp/bake (1.4.1): Downloading (100%)         
  - Installing squizlabs/php_codesniffer (3.0.2): Downloading (100%)         
  - Installing cakephp/cakephp-codesniffer (3.0.1): Downloading (100%)         
cakephp/app suggests installing markstory/asset_compress (An asset compression plugin which provides file concatenation and a flexible filter system for preprocessing and minification.)
cakephp/app suggests installing dereuromark/cakephp-ide-helper (After baking your code, this keeps your annotations in sync with the code evolving from there on for maximum IDE and PHPStan compatibility.)
cakephp/app suggests installing phpunit/phpunit (Allows automated tests to be run without system-wide install.)
cakephp/cakephp suggests installing lib-ICU (The intl PHP library, to use Text::transliterate() or Text::slug())
symfony/console suggests installing symfony/event-dispatcher ()
m1/env suggests installing m1/vars (For loading of configs)
symfony/var-dumper suggests installing ext-symfony_debug ()
psy/psysh suggests installing ext-pcntl (Enabling the PCNTL extension makes PsySH a lot happier :))
psy/psysh suggests installing ext-pdo-sqlite (The doc command requires SQLite to work.)
psy/psysh suggests installing hoa/console (A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit.)
composer/composer suggests installing ext-zip (Enabling the zip extension allows you to unzip archives)
cakephp/debug_kit suggests installing ext-sqlite (DebugKit needs to store panel data in a database. SQLite is simple and easy to use.)
Writing lock file
Generating autoload files
> Cake\Composer\Installer\PluginInstaller::postAutoloadDump
> App\Console\Installer::postInstall
Created `config/app.php` file
Set Folder Permissions ? (Default to Y) [Y,n]? y
Updated Security.salt value in config/app.php

/var/www/html #  exit
```

インストールとプロジェクトの作成が終わったらコンテナから出ます。

ここまでで準備はほとんど完了したので、サーバーを起動して画面を確認してみます。

```
$ cd data/htdocs/practice

$ ls
README.md		composer.lock		logs			src			vendor
bin			config			phpunit.xml.dist	tests			webroot
composer.json		index.php		plugins			tmp

$ bin/cake server

Welcome to CakePHP v3.5.0 Console
---------------------------------------------------------------
App : src
Path: /Users/home/cakephp/docker_cakephp3_tutorial/data/htdocs/practice/src/
DocumentRoot: /Users/home/cakephp/docker_cakephp3_tutorial/data/htdocs/practice/webroot
---------------------------------------------------------------
built-in server is running in http://localhost:8765/
You can exit with `CTRL-C`
```

無事にサーバー起動できました。

http://localhost:8765/ にアクセスして画面を確認してます。

![スクリーンショット 2017-08-24 11.19.16.png](https://qiita-image-store.s3.amazonaws.com/0/145671/69828ef1-993d-d13c-4a17-d6c7f38f28ba.png)

この画面が出れば成功です。お疲れ様でした。

これ以降はCakePHPチュートリアル (https://book.cakephp.org/3.0/ja/index.html) に沿って進めていくことも可能です。

## 追記

おそらく上記の方法で、サーバーがうまく動かない可能性があります(僕が実際そうでした)。

PHPの `intl`モジュールがDockerfileでインストールしているはずなのですが、うまく動きません。

なので、brewでmacのローカル環境にインストールしてあげます。

```
$ brew search intl
homebrew/php/php53-intl                homebrew/php/php55-intl                homebrew/php/php70-intl            homebrew/php/php72-intl
homebrew/php/php54-intl                homebrew/php/php56-intl                homebrew/php/php71-intl                intltool

```
バージョンによってインストールするものが変わるので、コンテナの中に入りPHPのバージョンを確認します。

```
$ docker exec -it dockercakephp3tutorial_phpfpm_1 /bin/sh
/var/www/html # php -v
PHP 7.1.8 (cli) (built: Aug  4 2017 19:03:42) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
/var/www/html # exit
```
バージョンが7.1.8なので、`php71-intl`をインストールします(僕の環境では`php70-intl`をインストールしていますが問題なく動作しています)。

```
$ brew install homebrew/php/php71-intl
```
これで、サーバーを起動すれば問題なく動くと思います。  `php71-intl`で動かなければ`php70-intl`を試してみてください。

## 終わりに

dockerでの環境構築からアプリケーション作成までの手順が乗ってるものが少なかったので、今回書いてみました。
何か問題がありましたら、コメント等お願いします。

以上、圧倒的環境構築でした。

PS:CakePHP3の情報は思った以上に少ないですね・・・


## さらに追記

この状態だとせっかく立てたmysqlのコンテナに接続できないです。
ローカルにmysqlがある場合はCakePHPプロジェクト配下にある `config/app.php`を編集すればローカルDBに接続できます。
dockerのmysqlに接続する方法が分かれば追記しようと思います。