Dockerでlaravel環境構築(php-fpm,nginx,mysql,redis)

#はじめに
Dockerをつかって開発環境作りたいと思います。
laravel使います！

#環境
Dockerはインストール済みということで。
fedoraでやってます

```
cat /etc/redhat-release
->Fedora release 24 (Twenty Four)
```
#Dockerで構築

##1.前提
docker-composeでやろうと思います。
docker-composeに関しては、公式をご参考ください。
[Install Docker Compose](https://docs.docker.com/compose/install/)

今回Dockerで立てるサーバーは、以下の四つです。

1.アプリケーションサーバー(以降、A)
2.ウェブサーバー(以降、W)
3.mysqlサーバー(以降、M)
4.redisサーバー(以降、R)

AとW,AとM,Rを繋ぐイメージでやります。
あと、AとWは少しいじりたいので、別でDocekrfile用意します。
MとRも永続化させようと思います。

構成的には下のようにしたいと思います。

```構成
laravel
 |_docker-compose.yml
 |_app.docker
 |_vhost.conf
 |_web.docker
 |_www
 |_mysql
 |_redis
```

まずは、laravelフォルダを作ります。
そして、dockerとhost間のデータ共有と永続化のために、
ディレクトリを作ります。

```
#laravelディレクトリ作成
mkdir laravel
#その他ディレクトリ作成
cd laravel
mkdir www
mkdir mysql
mkdir redis
```

##2.アプリケーションサーバー

###やること
-laravelをインストールするのに必要な、zipやcomposerを入れます。
-mysqlのその辺のやつをいれます
-userを新しく作って、そいつらのものにします。(dockerのアクセス権限の都合上、1000を振り分けます。)
-開いた時に/var/wwwにいるようにします。
-vimはとりあえず入れます。

###Dockerfile作成

```app.docker
FROM php:7-fpm

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 && \

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

    #user追加
    useradd -m -s /bin/bash -u 1000 meidaimae && \

    #www.conf修正
    sed -i 's/user\ \=\ www-data/user\ \=\ meidaimae/g' /usr/local/etc/php-fpm.d/www.conf && \
    sed -i 's/group\ \=\ www-data/group\ \=\ meidaimae/g' /usr/local/etc/php-fpm.d/www.conf
WORKDIR /var/www
```

##3.ウェブサーバー
やりたいこと
-nginx！
-こいつにもuserを追加してアプリケーションの方と合わせます。
-設定をhostのファイルからコピらせます。
-最初開く時/var/www（開くことあんまないかもやけど。）
-ドキュメントルートは/var/www/laravel/public

###Dockerfile作成

```web.docker
FROM nginx:latest

RUN useradd -m -s /bin/bash -u 1000 meidaimae && \
#nginx.conf
sed -i 's/user\ \ nginx\;/user\ \ meidaimae\;/g' /etc/nginx/nginx.conf

ADD ./vhost.conf /etc/nginx/conf.d/default.conf
WORKDIR /var/www
```
###vhost.conf作成

```vhost.conf
server {
    listen 80;
    index index.php index.html;
    root /var/www/laravel/public;

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

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
```

##4.docker-compose.yml作成
やりたいこと
-volumeでhostにデータを共有する
-linkでコンテナ間を通信出来るようにする

```docker-compose.yml
version: '2'
services:
    web:
        build:
            context: ./
            dockerfile: web.docker
        volumes:
            - ./www:/var/www
        ports:
            - "8000:80"
        links:
            - app
    app:
        build:
            context: ./
            dockerfile: app.docker
        volumes:
            - ./www:/var/www
        links:
            - mysql
            - redis
    mysql:
        restart: always
        image: mysql:latest
        volumes:
            - ./mysql:/var/lib/mysql
        environment:
            - "MYSQL_ROOT_PASSWORD=secret"
            - "MYSQL_DATABASE=laraveltest"
        ports:
            - "3306:3306"
    redis:
        restart: always
        image: redis:latest
        volumes:
            - ./redis:/data
        ports:
            - "6379:6379"
        command: redis-server --appendonly yes
```

##4.起動
コンテナ立ち上げます。

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

続けて、mysqlコンテナやredisコンテナの疎通確認をします。

```
#Aに入る
docker exec -it laravel_app_1 bash
#pingをうつ
ping laravel_web_1
ping laravel_mysql_1
ping laravel_redis_1
```

確認出来たらOK
ついでにhostもゲット!(172.20.0.3みたいなやつ)

##5.laravelインストール
###1.Aにlaravelを入れて、少し設定を変更します。(4でlaravel_app_1に入ったままの状態で。)

```
#meidaimae(上の過程で作ったユーザー)になってlaravelプロジェクト作成 (作成にまぁまぁ時間かかる。茶碗洗いとかできます。)
chown -R meidaimae:meidaimae /var/www
su meidaimae
composer create-project --prefer-dist laravel/laravel laravel

#redis使うのに必要なpredisをcomposerに追加
cd laravel
composer require predis/predis

#/var/www以下ののディレクトリとファイルのアクセス権を変更
find /var/www -type d -exec chmod 770 {} \;
find /var/www -type f -exec chmod 770 {} \;
```

###2.envを編集します
mysqlとredisの接続のため一部編集します。
編集対象の項目だけ書きます。(それぞれ目的に応じて変更してください)
laravel初心者なので、しょうみテキトーです。

```
DB_HOST=172.20.0.2#上記で確認したhostを入力
DB_DATABASE=laraveltest
DB_USERNAME=root
DB_PASSWORD=secret

CACHE_DRIVER=redis
SESSION_DRIVER=redis
REDIS_HOST=172.20.0.3#上記で確認したhostを入力
```



###3.mysqlのテーブルを作成
テーブル作ります！

```
php artisan make:migration create_user

cd /var/www/laravel/database/migrations
```

出来たファイルのupに下記を追加

```
        Schema::create('userstest', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });

```

その後、、artisanコマンドで、テーブルを作成する

```
cd /var/www/laravel
php artisan migrate 
```

mysqlコンテナに入って出来ているか確認

```
#passはsecretを指定。
mysql -h 172.20.0.2 -u root -D laraveltest -p

#table確認
show tables;
```
userstestテーブルが出来ていたらOK!
確認出来たらOK->exitする

###4.テスト用プログラム(色々テキトーです。)
テスト用でrouteにmysqlとredisのプログラムを書きます

```
vi /var/www/laravel/routes/web.php 
```

開いたら、下記を追加

```
Route::get('/testDB', function() {
    DB::insert('insert into userstest (name) values (?)', ['meidaimae']);
    $results = DB::table('userstest')->get();
    return $results;
});

Route::get('/testCache', function() {
    Cache::put('name', 'aaa',100);

    return Cache::get('name');
});
```

#動作確認

##ブラウザで確認
http://localhost:8000/testDB
http://localhost:8000/testCache

##ホンマに出来ているかコンテナに入って確認。(別ターミナルから入ってみるとか。)

###mysql
docker exec -it laravel_mysql_1 bash

```
#mysqlでテーブル作成(laraveltestのdbを選択、passはsecret)
mysql -u root -D laraveltest -p
#確認
select * from userstest;
```
入っとったらOK!

###redis

```
docker exec -it laravel_redis_1 bash
redis-cli

#上で指定した時間を過ぎてたら、ブラウザをもう一回叩く。
get laravel:name
ttl laravel:name
```
確認できたらOK!

#おわりに
開発環境、そしてあわよくば本番環境にDocker使いたいなと思い取り組み始めて、2ヵ月弱。
Dockerというよりインフラ周りの知識が少しついたような気がします。
#参考
[Docker laravel redisをつなげてみる]
(http://qiita.com/meidaimae/items/aa3dad468d62a417a3c6)
[Dockerの公式PHPのDockerfileを頑張って読んで理解しようとしてみた]
(http://unskilled.site/docker%E3%81%AE%E5%85%AC%E5%BC%8Fphp%E3%81%AEdockerfile%E3%82%92%E9%A0%91%E5%BC%B5%E3%81%A3%E3%81%A6%E8%AA%AD%E3%82%93%E3%81%A7%E7%90%86%E8%A7%A3%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%A6/)
[docker-composeでデータベースコンテナを立てるときのTips]
(http://blog.muuny-blue.info/9f067d8d6df2d4b8c64fb4c084d6c208.html#mysql)
[Dockerを使ってMysql]
(http://qiita.com/meidaimae/items/588aa6376a1479beb050)