Docker ComposeでLaravel6.5の環境を作成

少しDockerComposeについて勉強してみたので
試しにLaradockを使わずにDocker ComposeでLaravelの環境構築をしてみます
## 作成する環境
Laravel 6.5.2
php7.3
mysql 8.0.18
nginx 1.17

## ディレクトリ構成
```
project
├ docker-compose.yml
├ docker
|　 ├ php
│ 　│　 ├ php.ini
│ 　│ 　└ Dockerfile
│　 ├ nginx
│ 　│ 　└ default.conf
│ 　└ mysql
│ 　 　 ├ conf.d
│ 　 　 │  └ default_authentication.cnf
│ 　  　└ data
└ src
```

## PHP用のDockerfileを作成
```dockerfile:docker/php/Dockerfile
FROM php:7.3-fpm
COPY php.ini /usr/local/etc/php/

RUN apt-get update \
  && apt-get install -y zlib1g-dev libzip-dev mariadb-client \
  && docker-php-ext-install zip pdo_mysql

#Composer install
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# rootでのcomposerコマンド実行を許可
ENV COMPOSER_ALLOW_SUPERUSER 1
# composerのグローバルパッケージがインストールされるディレクトリの指定
ENV COMPOSER_HOME /composer
# composerのパスを通す
ENV PATH $PATH:/composer/vendor/bin
# laravelインストール
RUN composer global require "laravel/installer"

RUN curl -SL https://deb.nodesource.com/setup_14.x | bash
RUN apt-get install -y nodejs && \
  npm install -g npm@latest && \
  npm install -g @vue/cli

WORKDIR /var/www
```
## php.iniの設定
```ini:docker/php/php.ini
; timezone
date.timezone = Asia/Tokyo

; error reporing
log_errors = On
error_log = /dev/stderr
display_errors = Off

; mbstring
mbstring.language = "Japanese"
```
timezoneを東京に
errorログを標準出力エラーに設定
デフォルトで使用する言語を日本語に設定

## nginxの設定ファイルを記述
```conf:docker/nginx/default.conf
server {
  listen 80;

  root  /var/www/public;
  index index.php;

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

  location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass   php-fpm:9000;
    fastcgi_index  index.php;

    include        fastcgi_params;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param  PATH_INFO $fastcgi_path_info;
  }
}
```
fastcgi_pass   php-fpm:9000;のphp-fpmにはdocker-compose.ymlで定義したサービス名を指定します。

## mysql
MySQL8系のデフォルト認証形式を変更するための設定ファイルを作成します

```conf:docker/mysql/conf.d/default_authentication.cnf
[mysqld]
default_authentication_plugin= mysql_native_password
```

続いて、mysqlのデータを永続化するためのディレクトリを作成します

```bash
$ mkdir /docker/mysql/data
```


## docker-compose.ymlの作成
```yml:docker-compose.yml
version: '3'
services:
  nginx:
    image: nginx:1.17-alpine # nginxのimageにnginx:1.17-alpineを指定
    container_name: "nginx"
    ports:
      - "8080:80" # ホストの8080ポートでnginxコンテナの80にアクセス
    volumes:
      - ./src:/var/www # ホストのsrcをnginxコンテナの/var/wwwにマウント
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf # 作成したdefault.confを/etc/nginx/conf.d/default.confにマウント
    depends_on: # コンテナの依存関係を定義する
      - php-fpm # php-fpmの起動後にnginxを起動
  php-fpm:
    build: ./docker/php # ./docker/php/Dockerfileをbuildしてイメージ作成
    container_name: "php-fpm"
    volumes:
      - ./src:/var/www # ホストのsrcをphp-fpmコンテナの/var/wwwにマウント
    links: # コンテナと他のサービスを繋げる
      - db
    depends_on:
      - db # dbの起動後にphp-fpmを起動
  db:
    image: mysql:8.0.18 # mysqlのimageにmysql:8.0.18を指定
    container_name: "db"
    volumes:
      - ./docker/mysql/conf.d:/etc/mysql/conf.d # mysqlのせってファイルをマウント
      - ./docker/mysql/data:/var/lib/mysql # mysqlのデータ永続化
    ports:
      - 3306:3306
    environment:
      MYSQL_DATABASE: hogehoge
      MYSQL_USER: hoge
      MYSQL_PASSWORD: hoge
      MYSQL_ROOT_PASSWORD: root
      TZ: "Asia/Tokyo"
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
``` 

## コンテナ起動
```bash
$ docker-compose build
$ docker-compose up -d
```
## laravelのプロジェクトファイル作成
```bash
$ docker-compose exec php-fpm composer create-project --prefer-dist "laravel/laravel=6.5.2" .
```
## 確認
これで[http://localhost:8080](http://localhost:8080)にアクセスするとlaravelのページが表示されます
![スクリーンショット 2019-11-29 20.37.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273496/adcbfa2b-80e0-afa3-97cf-f3e2bfff16bf.png)

##　laravelの認証画面まで作ってみる
```bash
$ docker-compose exec php-fpm composer require laravel/ui
$ docker-compose exec php-fpm php artisan ui vue --auth
$ docker-compose exec php-fpm npm run dev
```
php artisan make:auth　をしたら怒られました、、、laravel6で変更されたんですね

このためにDockerfileで下記を書いています

```Dockerfile
RUN curl -SL https://deb.nodesource.com/setup_13.x | bash
RUN apt-get install -y nodejs && \
  npm install -g npm@latest && \
  npm install -g @vue/cli
```

## 再度確認
[http://localhost:8080/register](http://localhost:8080/register)
無事ユーザー登録ページが表示されました
![スクリーンショット 2019-11-29 20.36.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273496/149cd99f-eb27-b9af-c963-fbe9fb859295.png)

## 登録してみる
怒られた、、、
![スクリーンショット 2019-11-29 20.40.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273496/2666675c-34f5-b497-eb3e-0e9907fe1962.png)

## laravelの.envでDBの設定を忘れていたので設定
```env:src/.env
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=hogehoge
DB_USERNAME=hoge
DB_PASSWORD=hoge
```
DB_HOST
DB_DATABASE
DB_USERNAME
DB_PASSWORD
をdocker-compose.ymlで定義したものに変更してください
DB_HOSTはDBコンテナのサービス名です

## 認証用のテーブルも作り忘れていたので作成
```
$ docker-compose exec php-fpm php artisan migrate
```

## 再度作成！
いけた！！！
![スクリーンショット 2019-11-29 22.48.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273496/df9fe03e-89a2-0df1-015a-03d2dbea5e79.png)

まだまだDocker勉強中で間違っている所があるかと思いますので
ご指摘ありましたらよろしくお願いいたします🙇‍♂️