Dockerでlaravelの開発環境構築をしてみた (php-pfm,nginx, mysql)

おはようございます。

タイトルの通りに今日はDockerでlaravelの環境構築経験を述べたいと思います。

私はまだ日本語を勉強中なので。わかりにくいことがあれば申し訳ありません。

よろしくお願いします。

#開発環境
（Dockerでの環境ではなく、Dockerをインストール環境です）
docker : Docker version 17.06.0-ce, build 02c1d87
docker-compose : docker-compose version 1.15.0, build e12f3b9
docker-machine : docker-machine version 0.12.1, build c8b17e8
OS : Ubuntu

Distributor ID: Ubuntu 
Description: Ubuntu 16.04.2 LTS
Release: 16.04
Codename: xenial

#Dockerで構築したい環境
* Webserver : Nginx 1.0
* Database : mysql 5.6
* PHP:7.0.4-FPM

ということで、ステップを順序に述べたいと思います。

## 1. Laravelプロジェクトを作成
まずはプロジェクトを置きたい場所に入りましょう。
`cd projects`
 
アーカイブの形でサンプルのプロジェクトをダウンロードします。今の最新のバージョンを選びます。
`curl -L https://github.com/laravel/laravel/archive/v5.4.30.tar.gz | tar xz`

ダウンロードしたプロジェクトの名前は「laravel-5.4.30」みたいでしょう。自分が好きなプロジェクト名に変更して、入ります。

```
mv laravel-5.4.30 sample-laravel
cd sample-laravel
```

よっし、サンプルのプロジェクトができました。次は composerでライブラリーをインストールしましょう。

## 2. Composerで関係のライブラリーをインストール
`docker run --rm -v $(pwd):/app composer/composer install`

説明：

* dockerのコンテナーを起動します。このコンテナーのベースイメージは「composer/composer」になります。意図は今のディレクトリをコンテナーの中にマウントして、そこで「composer install」を実行するということです。実行場所はcontainerの中ですが、マウントされているので、ホストにも反映されますね。
* `--rm` :コンテナーが終わり次第、意外に生まれるファイルも一緒に削除。
* `-v $(pwd):/app` : 今のホストの場所（pwd)をコンテナーの「/app」にマウントします。「install」はここに実行されるでしょう。

Note : 
実際に普通の権限で実行すると、「compose.json」が見つからない問題がありました。その時は「sudo」コマンドを実行しました。私の場合は「sudo」と普通ユーザーの実行とマウント問題があります。


## 3. docker-composeで設定
設定ファイルの4つを作成します。
1. docker-compose.yml : サービスの定義。今回は3つのサービスを定義します：app, web, database
2. app.dockerfile : appサービスが利用するイメージをビルドするためのdockerfile
3. web.dockerfile : webサービスが利用するイメージをビルドするためのdockerfile
4. vhost.conf : webサービスのnginx設定

次は各サービス方向で述べたいと思います。

### 3.1. appサービス
**docker-compose.yml**

```
version: '3'
services:

  # The Application
  app:
    build:
      context: ./
      dockerfile: app.dockerfile
    working_dir: /var/www
    volumes:
      - ./:/var/www/
 
```

`version: '3'` : docker-compose バージョン、3を選びます。version 2と相違がありますので、ご注意をください。
`context` : dockerfileを置きる場所
`volumes` : 今いるディレクトリ（ホスト）をコンテナーの`/var/www`にマウントします。

ファイル中身全体は後でまとめます。

**app.dockerfile**
コンテナーで利用するソフトを記載する場所

```
FROM php:7.0.4-fpm

RUN apt-get update && apt-get install -y libmcrypt-dev \
    mysql-client libmagickwand-dev --no-install-recommends \
    && pecl install imagick \
    && docker-php-ext-enable imagick \
    && docker-php-ext-install mcrypt pdo_mysql
```

### 3.2. webサービス
webサービスは外のリクエストを受けてから、そのクエストをappサービスに渡るという形式です。
ウェブサーバーのapacheとnginx両方がありますが、今回私はnginxを選びます。
**docker-compose.yml**
webサービスの設定

```
  # The Web Server
  web:
    build:
      context: ./
      dockerfile: dev.web.dockerfile
    working_dir: /var/www
    ports:
      - 8080:80
```

`ports : -8080:80` ホストの8080ポータルをコンテナーの80に紐付けます。

**web.dockerfile**
コンテナーをビルドする指定
```
FROM nginx:1.10
ADD vhost.conf /etc/nginx/conf.d/default.conf
```

**vhost.conf**

```
server {
      listen 80;
      index index.php index.html;
      root /var/www/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;
          sendfile off;
      }
}
```

`fastcgi_pass app:9000;`リクエストをappというホストに渡します。

### 3.3. databaseサービス
**docker-compose.yml**

```
  # The Database
  database:
    image: mysql:5.6
    volumes:
      - dbdata:/var/lib/mysql
    environment:
      - "MYSQL_DATABASE=homestead"
      - "MYSQL_USER=homestead"
      - "MYSQL_PASSWORD=secret"
      - "MYSQL_ROOT_PASSWORD=secret"
    ports:
        - "33061:3306"

volumes:
  dbdata:

```

`image: mysql:5.7`公開mysqlイメージをベースにしてコンテナを構築指定
`volumes  dbdata:` コンテナーが走らなくてもこのボリュームがなくならないように設定

これまでサービスの定義が終わりました。下記は`docker-compose`全体です。

```
version: '3'
services:

  # The Application
  app:
    build:
      context: ./
      dockerfile: app.dockerfile
    working_dir: /var/www
    volumes:
      - ./:/var/www/
 
  # The Web Server
  web:
    build:
      context: ./
      dockerfile: web.dockerfile
    working_dir: /var/www
    ports:
      - 8080:80
  
  # The Database
  database:
    image: mysql:5.6
    volumes:
      - dbdata:/var/lib/mysql
    environment:
      - "MYSQL_DATABASE=homestead"
      - "MYSQL_USER=homestead"
      - "MYSQL_PASSWORD=secret"
      - "MYSQL_ROOT_PASSWORD=secret"
    ports:
        - "33061:3306"

volumes:
  dbdata:
```

これで構築が終わりますが、laravel通常の設定はまだですから、いまからlaravelを設定します。まずは`docker-compose`サービスを走らせて、コンテナーに入って設定しましょう。

## 4.サービスを走る
コマンド：
`docker-compose up`


appサービスのコンテナーに入ります。
`docker-compose exec app /bin/bash`

**環境変数作成**
.envファイル作成
`cp .env.example .env`

**キー作成**
`php artisan key:generate`

**キャッシュクリアー**
`php artisan cache:clear`

storageディレクトリはアクセス問題があれば：
`chmod -R 777 storage`

ここでブラウザーで確認できると思います。
http://0.0.0.0:8080



#おわりに
dockerのおかげであまりサーバー構築がわからない私は自分でも簡単に構築できてよかったと思います。
次は本番環境の構築設定について話したいと思います。

今回のgit repoは↓です。
Git repo : https://github.com/mytv1/sample-docker-laravel

参考：
http://qiita.com/meidaimae/items/1b5902e2e520ece34b9a#dockerfile%E4%BD%9C%E6%88%90
https://medium.com/@shakyShane/laravel-docker-part-1-setup-for-development-e3daaefaf3c