いまさらDocker ComposeでFuelPHP + Nginx + MySQL + PHP7の環境を作る。

## はじめに
久方ぶりに仕事でFuelPHPの環境が必要になったけど、ローカル環境を汚したくなかったので、いまさらdocker-composeでの環境を作成した。    

## 実行環境

* macOS High Sierra v10.3
* docker v17.09.0-ce
* docker-compose v1.16.1

## Docker Compose

ソースは以下にあります。
https://github.com/nemui-fujiu/docker_fuelphp

以下のような構成で作成する。

```
.
├── README.md
├── docker-compose.yml
├── nginx
│   ├── Dockerfile
│   └── server.conf
├── php7
│   └── Dockerfile
└── www
    └── fuel_server
```

docker composeの記載はこんな感じ。

* nginx
* php-fpm
* mysql
* redis

今回特にRedisは必要ないけどなんとなくいれとく。

```docker-compose.yml
version: '2'
services:
    web:
        container_name: fuel_web
        build:
            context: ./nginx/
            dockerfile: Dockerfile
        volumes:
            - ./www:/var/www
        ports:
            - "9080:80"
        links:
            - app
    app:
        container_name: fuel_app
        build: 
            context: ./php7/
            dockerfile: Dockerfile
        volumes:
            - ./www:/var/www
            - ./tmp/mysqld:/var/run/mysqld
        links:
            - mysql
            - redis
    mysql:
        container_name: fuel_mysql
        restart: always
        image: mysql:latest
        volumes:
            - ./mysql:/var/lib/mysql
            - ./tmp/mysqld:/var/run/mysqld
        environment:
            - "MYSQL_DATABASE=fuel_db"
            - "MYSQL_ROOT_PASSWORD=fuel_db_password"
        ports:
            - "13306:3306"
    redis:
        container_name: fuel_redis
        restart: always
        image: redis:latest
        volumes:
            - ./redis:/data
        ports:
            - "16379:6379"
        command: redis-server --appendonly yes
```

NginxのDockerファイルは以下

```linux:nginx/Dockerfile
FROM nginx:latest
MAINTAINER s-fujiu

ADD ./server.conf /etc/nginx/conf.d/default.conf
WORKDIR /var/www
```
Nginxのserver.confは以下
設定はいろいろ書いておく。

```nginx:nginx/server.conf
server {
    listen 80;
    server_name  localhost;
    index index.html index.htm index.php;
    root /var/www/fuel_server/public;

    charset utf-8;

    # アクセスログの設定
    access_log /var/log/nginx/app_access.log;
    # エラーログの設定
    error_log /var/log/nginx/app_error.log;

    location / {
        try_files $uri $uri/ /index.php?q=$uri&$args;
    }

    location ~ \.php$ {
        try_files                $uri = 404;
        include                  /etc/nginx/fastcgi_params;
        fastcgi_pass             app:9000;
        #fastcgi_pass            unix:/var/run/php-fpm.sock;

        fastcgi_index            index.php;
        fastcgi_split_path_info  ^(.+\.php)(/.+)$;

        fastcgi_param            SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param            PATHINFO        $fastcgi_path_info;
        fastcgi_param            PATH_TRANSLATED $document_root$fastcgi_path_info;
    }

    error_page 404 /index.php;

    client_max_body_size 8M;

    #--------------------
    # 静的ファイル設定
    #--------------------
    # 画像やCSSにはキャッシュの有効期限を設定＆アクセスログOFF
    location ~ \.(html|css|js|jpe?g|png|gif|svg|mpg|flv|swf)$ {
        expires 10d;
        access_log off;
        break;
    }

    # .gitや.htaccessにはアクセス禁止
    location ~ /\.(ht|git|svn) {
        deny all;
    }

    # faviconへのアクセスは記録しない
    location = /favicon.ico {
        access_log off;
        log_not_found off;
    }

    # robots.txtへのアクセスは記録しない
    location = /robots.txt {
        access_log off;
        log_not_found off;
    }
}
```

php-fpmのDockerfileはこんな感じ

```linux:php7/Dockerfile
FROM php:7-fpm
MAINTAINER satoshi.fujiu

RUN apt-get update && apt-get install -y libmcrypt-dev mysql-client \
    && docker-php-ext-install mcrypt pdo_mysql && \
    #zip,unzip
    apt-get install -y zip unzip && \
    #vim
    apt-get install -y vim curl

    #composer
RUN curl -sS https://getcomposer.org/installer | php && \
    mv composer.phar /usr/local/bin/composer && \
    chmod 777 /usr/local/bin/composer

RUN cd /var/www && \
    curl https://get.fuelphp.com/oil | sh

WORKDIR /var/www
```

作成できたら、docker-composeを実行

```
docker-compose up --build -d
```

ここからはFuelPHPプロジェクトの作成

## 既存プロジェクトがある人

docker-composeの

```diff:docker-compose.yml
    mysql:
        container_name: fuel_mysql
        restart: always
        image: mysql:latest
        volumes:
            - ./mysql:/var/lib/mysql
            - ./tmp/mysqld:/var/run/mysqld
        environment:
-            - "MYSQL_DATABASE=fuel_db"
-            - "MYSQL_ROOT_PASSWORD=fuel_db_password"
+            - "MYSQL_DATABASE={既存プロジェクトデータベース}"
+            - "MYSQL_ROOT_PASSWORD={既存プロジェクトパスワード}"
```

wwwディレクトリ直下にプロジェクトフォルダを配置して、nginxのserver.confを変更してください。

```diff:nginx/server.conf
server {
    listen 80;
    server_name  localhost;
    index index.html index.htm index.php;
-    root /var/www/fuel_project/public;
+    root /var/www/{既存プロジェクト名}/public;

    charset utf-8;

    # アクセスログの設定
    access_log /var/log/nginx/app_access.log;
    # エラーログの設定
    error_log /var/log/nginx/app_error.log;
```




## 新規プロジェクト作成する人

公式ページにインストール方法が書いてあるのでそのまま実行。
http://fuelphp.jp/docs/1.7/installation/instructions.html
実行時にエラーが出る人は以下のように変更して実行するとうまくいく。

準備ができたらプロジェクト作成
fuel_appコンテナに入って作業する。

```
docker exec -it fuel_app bash
curl https://get.fuelphp.com/oil | sh
oil create fuel_server
```


チュートリアルに合わせて対応

configファイルの時間がコメントアウトされているので変更する。

```php:fuel/app/config.php
'default_timezone'   => 'Asia/Tokyo',
```

合わせて、ORMを使いたいのでコメントアウトされている以下の箇所を変更する。

```php:fuel/app/config.php
'always_load'  => [
　　　　'packages'  => [
　　　　　　　　'orm',
　　　　],
],
```


DBの設定は以下。

```php:fuel/app/config/development/db.php
return [
    // MySQL ドライバの設定
    'default' => [
        'type'           => 'pdo',
        'connection'     => [
            'dsn'            => 'mysql:host=fuel_mysql;dbname=fuel_db',
            'username'       => 'root',
            'password'       => 'fuel_db_password',
            'persistent'     => false,
            'compress'       => false,
        ],
        'identifier'   => '`',
        'table_prefix'   => '',
        'charset'        => 'utf8',
        'enable_cache'   => true,
        'profiling'      => false,
    ],
];
```

Scaffoldを使ってファイルを自動生成

```
php oil generate scaffold post title:varchar[50] body:text
```

結果エラーが出てしまいます。

```
Uncaught exception Fuel\Core\PhpErrorException: A non-numeric value encountered
Callstack:
#0 /var/www/fuel_project/fuel/core/bootstrap.php(103): Fuel\Core\Errorhandler::error_handler(2, 'A non-numeric v...', '/var/www/fuel_p...', 1790)
#1 /var/www/fuel_project/fuel/packages/oil/classes/generate.php(1790): {closure}(2, 'A non-numeric v...', '/var/www/fuel_p...', 1790, Array)
#2 /var/www/fuel_project/fuel/packages/oil/classes/generate.php(1177): Oil\Generate::_find_migration_number()
#3 /var/www/fuel_project/fuel/packages/oil/classes/generate/scaffold.php(131): Oil\Generate::migration(Array, false)
#4 [internal function]: Oil\Generate_Scaffold::forge(Array, 'orm')
#5 /var/www/fuel_project/fuel/packages/oil/classes/command.php(81): call_user_func('Oil\\Generate_Sc...', Array, 'orm')
#6 /var/www/fuel_project/oil(68): Oil\Command::init(Array)
#7 {main}
```

PHP7で環境構築している関係でgenerateコマンドを実行するとエラーになるので、以下を変更

```
vim /var/www/fuel_project/fuel/packages/oil/classes/generate.php
```

以下、1790行目の数値変換が正しく行えていないため、(int)キャストを追加する。

```php:fuel/packages/oil/classes/generate.php
                catch (\LogicException $e)
                {
                        throw new Exception("Unable to read existing migrations. Path does not exist, or you may have an 'open_basedir' defined");
                }

                return str_pad($last + 1, 3, '0', STR_PAD_LEFT);
        }

        private static function _update_current_version($version)
        {
```

以下のように修正

```diff:generate.php
- return str_pad($last + 1, 3, '0', STR_PAD_LEFT);
+ return str_pad((int)$last + 1, 3, '0', STR_PAD_LEFT);
```

次にmigrateを叩いてDBにテーブルを作成します。

```
php oil refine migrate
```

あとは以下URLで表示できるので完了。

## TOP
http://localhost:9080

<img width="1346" alt="スクリーンショット 2017-11-04 9.35.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/50276/1169f688-703a-6275-8e3d-b1647dd9f763.png">

## Post
http://localhost:9080/post
<img width="1348" alt="スクリーンショット 2017-11-04 9.35.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/50276/259cf6b8-4d57-01e0-ca88-8a3bf2c87bb9.png">


以上です、お疲れ様でした。