dockerでLaravel環境構築

##はじめに
dockerによってLaravelの環境構築を行います。できるだけシンプルな構成を目指します。laradockは使いません。

自分は以前laradockを使っていましたが、
・プロジェクトが必要以上に大きくなる
・dockerの知識がほとんどなくても環境構築できでしまう
これらの点からlaradockを使わない方法を試していきます。

laradockはとりあえずdockerでLaravelを立ち上げたい方、知識が全くない方は使うとよいかもしれません。

以前にlaradockによるlaravelの環境構築の記事を書きましたので、laradockを使いたい方はこちらを→https://qiita.com/rope19181/items/da31dc2cd6097315fa10

##環境・仕様
・nginx上でPHP実行環境を構築し、Laravel新規プロジェクト作成。
・mysqlとwebGUIとしてphpmyadminも使えるようにします。

・環境、仕様は以下の通りです。
Docker version 19.03.5
docker-compose version 1.24.1
php 7.2-fpm
mysql 5.7

##構成
最終的にこのような構成となります。

project
├ docker
│ 　├ db
│ 　│  ├ data 
│ 　│  ├ my.conf
│ 　│  └ sql
│ 　│
│　 ├ nginx
│ 　│　 └ default.conf
│ 　│ 　
│　 └ php
│ 　  ├ Dockerfile 
│ 　　└ php.ini 　
├ myapp
└ docker-compose.yml

今回はprojectをルートディレクトリとしています。

`./myapp`はlaravelのプロジェクトを置くディレクトリとなります。

##docker-compose.ymlの作成
docker-composeでは複数のコンテナを管理、構築するためにdocker-compose.ymlに各コンテナの環境設定を定義します。

```yml:docker-compose.yml

version: '3'

services:
  php:
    container_name: php
    build: ./docker/php
    volumes:
      - ./myapp/:/var/www

  nginx:
    image: nginx
    container_name: nginx
    ports:
    - 80:80
    volumes:
    - ./myapp/:/var/www
    - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
    - php

  db:
    image: mysql:5.7
    container_name: db-host
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: database
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
      TZ: 'Asia/Tokyo'
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
    - ./docker/db/data:/var/lib/mysql
    - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
    - ./docker/db/sql:/docker-entrypoint-initdb.d
    ports:
    - 3306:3306

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=db-host
      - PMA_USER=docker
      - PMA_PASSWORD=docker
    links:
      - db
    ports:
      - 8080:80
    volumes:
      - /sessions
```

各項目について簡単に説明します。
詳しくは公式リファレンスを見てみましょう。https://docs.docker.com/compose/compose-file/

####image
ローカルやリモートにあるイメージを指定します。ローカルにない場合リモートからpullされます。

今回はnginx、mysql、phpmyadminはリモートのイメージを指定しています。

####build
イメージをbuildする際に参照するファイルを指定します。
要はイメージを構築する場合はこちらを使うわけです。またbuildとimageを両方指定することはできません。

今回はphpコンテナの構築でDockerfileを使うため、そのディレクトリのパスを指定しています。

####volumes
ボリュームとしてマウントするパスを指定します。`ホスト:コンテナ`またアクセスモードを読み取り専用する場合`ホスト:コンテナ:ro`とします。

今回はアクセスモードを指定しないため`rw`となり、書き込みもできるボリュームです。

####ports
公開(expose)するポートをします。`ホスト:コンテナ`とします。

ポートが被る場合はここを変更します。

####links
コンテナにリンクさせるサービス名を指定します。
注）**コンテナ名**(`container_name`)ではなく**サービス名**

今回はphpmyadminのコンテナにてdb-hostコンテナのサービス名である`db`を指定しています。


##phpのDockerfileの作成

phpコンテナではLaravelの実行のためにcomposerのインストールします。
公式(https://getcomposer.org/download/) から下の部分を`#Composer install`のところに貼り付けます。

<img width="804" alt="スクリーンショット 2020-02-10 18.55.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502145/acc1d444-349c-1c8a-4bd2-5dcf6bea092c.png">

```dockerfile:Dockerfile
FROM php:7.2-fpm
COPY php.ini /usr/local/etc/php/

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

#Composer install
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php -r "if (hash_file('sha384', 'composer-setup.php') === 'c5b9b6d368201a9db6f74e2611495f369991b72d9c8cbd3ffbc63edff210eb73d46ffbfce88669ad33695ef77dc76976') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
RUN php composer-setup.php
RUN php -r "unlink('composer-setup.php');"
RUN mv composer.phar /usr/local/bin/composer

ENV COMPOSER_ALLOW_SUPERUSER 1

ENV COMPOSER_HOME /composer

ENV PATH $PATH:/composer/vendor/bin


WORKDIR /var/www

RUN composer global require "laravel/installer"
```
##PHP設定ファイルの作成
docker/php/にphp.iniを作成します。

```ini:php.ini

[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"
```

##nginxの設定ファイルの作成
docker/nginxにdefault.confを作成します。

```conf:default.conf

server {
  listen 80;
    index index.php index.html;
    root /var/www/public;

  location / {
    root /var/www/public;
    index  index.html index.php;
    }

  location ~ \.php$ {

    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass php:9000;
    fastcgi_index index.php;
    include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      fastcgi_param PATH_INFO $fastcgi_path_info;
  }
 }
```
##dockerの起動
下記コマンドでdockerを起動させます。初回は結構時間がかかります。
docker-composeでは`up`によってイメージの構築、コンテナの起動を行いますが、初回はキャッシュがないため`--build`をつけます。`-d`オプションによってバックグラウンドで起動させます。

```shell

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

##laravelプロジェクトの作成
まずはphpコンテナに入ります。コンテナに入る場合は`exec`コマンドを実行します。

```shell

$ docker-compose exec php bash
```
laravelの新規プロジェクトを作成します。

```shell

composer create-project --prefer-dist laravel/laravel=5.8.* .
```
バージョンはなるべく指定するようにしましょう。

##laravelプロジェクトの環境設定

laravelプロジェクト内の.envやconfig/detabase.phpのデータベースの設定を変更します。
DB名、ユーザ名、パスワードなどを先ほどdocker-compose.ymlに設定した値に変更しましょう。

##動作確認

####nginx、php
http://localhost にアクセスしlaravelのホームページが表示されればOK。

<img width="634" alt="スクリーンショット 2020-02-11 00.24.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502145/b29dc638-6d4a-cf5c-0fc6-16b71d2398b3.png">

####mysql、phpmyadmin
phpコンテナに入り、migrateします。

```shell

$ docker-compose exec php bash

$ php artisan migrate
```

http://localhost:8080 にアクセスし、phpmyadminが立ち上がりDB内に2つのテーブルが作成されていれば成功。

<img width="465" alt="スクリーンショット 2020-02-11 00.23.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502145/55eb4312-65e7-b74f-2434-c2c20a052cf2.png">

##docker-composeコマンド小まとめ
よく使うものをまとめます。
###up 
コンテナの構築、起動をします。

似たものとしてイメージの構築のみを行う`build`、コンテナの起動のみを行う`start`などがありますが、docker-composeではとりあえず`up`をしとけばいいと思います。
Dockerfileを更新した時などは`build`しましょう。

```shell
$ docker-compose up -d  
$ docker-compose up -d --build #初回の起動などbuildもしたいとき
```

###down
`up`で作られたものを削除します。`down`だけだとコンテナとネットワークの削除を行います。オプションによってその範囲を指定します。

```shell
$ docker-compose down
```
コンテナ、イメージ、ボリュームそしてネットワークすべてを削除したい場合は

```shell
$ docker-compose down --rmi all --volumes
```

###exec
起動中のコンテナでコマンドを実行

```shell

$ docker-compose exec コンテナ名 実行するコマンド

$ docker-compose exec コンテナ名 bash #コンテナに入る場合
```

##最後に
laradockも簡単にできますが、少しの知識があればこちらの方法のほうがシンプルで分かりやすいと思います。

laradockを使いたい方はこちら→https://qiita.com/rope19181/items/da31dc2cd6097315fa10