DockerでLaravel+MySQL+phpMyadminの環境構築

この記事では新卒未経験エンジニアがLaravelの環境構築を解説します。至らない点もありますが、よろしくお願いします。gitを使わずに行います。Dockerfileやdocker-compose.ymlなどの設定ファイルの解説もしています。設定をしっかり理解して環境構築したい人向けです。また、Laravel初心者の方向けです！。



動作環境
Mac（Catallina 10.15.7）
Docker  19.03.13
docker-compose 1.27.4

dockerやdocker-composeは事前にインストールしておいてください。
参考記事
[dockerとdocker-composeのインストール(mac編)](https://qiita.com/tomokei5634/items/7b1e7a121d5d7bc12116)



##ディレクトリ構成

```
├── Docker/
│   ├── App/
│   │   ├ 000-default.conf  
│   │   ├ Dockerfile
│   │   └ php.ini 
│   └── DB/
│        ├ my.cnf  
│        └ volume/ 
│
├── src/ 
└── docker-compose.yml
```

このような表示の仕方を行うためのtreeコマンドについてこちらで記事にしています。
[ディレクトリ構成を簡単に表示！treeコマンド（Mac）よく使うオプションも紹介](https://qiita.com/tatema/items/8a1de3d3b87884cb0d21)

####各ファイル・ディレクトリの説明
<dl>
<dt>000-default.conf</dt>
<dd>Apacheの設定ファイル</dd>
<dt>Dockerfile</dt>
<dd>Dockerの設定ファイル</dd>
<dt>php.ini</dt>
<dd>PHPの設定ファイル</dd>
<dt>my.conf</dt>
<dd>MySQLの設定ファイル</dd>
<dt>volumeディレクトリ</dt>
<dd>DBのデータが保存される（永続化される）</dd>
<dt>srcディレクトリ</dt>
<dd>Laravelのソースコードが収納されるディレクトリ</dd>
<dt>docker-compose.yml</dt>
<dd>docker-composeの設定ファイル</dd>
</dl>



##各設定ファイル

####000-default.conf
Apacheの設定になります。
以下の内容を記載してください。

```ruby:000-default.conf
<VirtualHost *:80>
       ServerAdmin laravel@localhost
       DocumentRoot /var/www/html/laravelapp/public
       ErrorLog ${APACHE_LOG_DIR}/error.log
       CustomLog ${APACHE_LOG_DIR}/access.log combined
       <Directory /var/www/html/laravelapp/public>
           AllowOverride All
       </Directory>
</VirtualHost>
```

+ 1行目:ポート80番に対するバーチャルホストの設定を行うことを定めています。

+ 2行目：サーバーのアドレスです。laravel@localhostというアドレスでリクエストが送られた場合、今記載しているバーチャルホストを使うという意味です。今回はローカルなので適当です。


+ ３行目:エラーログのディレクトリパスを指定しています。*

+ 4行目:アクセスログのディレクトリパスを指定しています。*

+ 5~7行目：作成するコンテナ内にある`.htaccess`というコンテキストを持つ全てのディレクティブが利用できる。


*${APACHE_LOG_DIR}は作成した後のコンテナの中の`/etc/apache2/envvars`に定義されています。



　参考記事
　　[名前ベースの仮想ホスト](https://www.adminweb.jp/apache/virtual/index2.html)
　　[一つのApacheサーバーで複数ドメインのサイトを公開する方法](https://dawaan.com/apache-multiple-sites/)
　　[メモ：Apacheの設定ファイル(http.conf)を確認する (1)](https://qiita.com/KoriCori/items/e4fc93482f9b434a92cd)

####Dockerfile
php（laravel）コンテナの設定になります。
以下の内容を記載してください。

```ruby:Dockerfile
FROM php:7.4-apache

ADD php.ini /usr/local/etc/php/
ADD 000-default.conf /etc/apache2/sites-enabled/

RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer

RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
vim \
libpng-dev \
libpq-dev \
&& docker-php-ext-install pdo_mysql

RUN mv /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled
RUN /bin/sh -c a2enmod rewrite
```

```FROM php:7.4-apache```
DockerHubからphp:7.4-apacheというイメージを引っ張ってきています。

`ADD php.ini /usr/local/etc/php/
ADD 000-default.conf /etc/apache2/sites-enabled/`
後ほど説明するphp.iniと上記で説明した000-default.confを作成するコンテナ内の指定したディレクトリにコピーしています。

`RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer`
コンテナ内で、laravelのインストールに必要なコンポーザーをインストールしています。


`RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
vim \
libpng-dev \
libpq-dev \
&& docker-php-ext-install pdo_mysql`
コンテナ内でミドルウェアをインストールしています。コンテナ内でgit,zip,unzip,vim,libpng-dev,libpq-dev が使えるようにしています.

`RUN mv /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled
RUN /bin/sh -c a2enmod rewrite`
コンテナ内で、rewrite.loadを指定したディレクトリに移動するmvコマンドを実行しています。
その後、rewrite.loadを有効にするた目のコマンドを実行しています。詳しくは二つ目の参考資料をご覧ください。

参考資料
[Apacheのディレクトリを理解しよう](https://kana-linux.info/linux/apache%E3%81%AE%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%82%92%E7%90%86%E8%A7%A3%E3%81%97%E3%82%88%E3%81%86)
[UbuntuにてApacheのモジュールを有効化する](https://www.t3a.jp/blog/infrastructure/apache2-mod-add/)
[DockerでLaravel+Apache+MySQLの開発環境を構築する](https://note.com/pocke_techblog/n/n8af813848fa0)


####php.ini
phpの設定になります。
下記をコピペしてください。

```ruby:php.ini
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
default_charset = "UTF-8"
mbstring.language = "Japanese"
```
`date.timezone = "Asia/Tokyo"`
文字通りタイムゾーンの設定をしています。
`default_charset`
HTTPヘッダに出力するデフォルトの文字コードを指定します。
`mbstring.language = "Japanese"`
デフォルトの言語を設定します。

参考資料
[php.ini ディレクティブのリスト](https://www.php.net/manual/ja/ini.list.php)
[php.ini設定で設定可能な項目について](https://www.xserver.ne.jp/manual/man_server_phpini_setting_item.php)
[php.iniの編集](https://qiita.com/hikotaro_san/items/0aab2a53726674c50868)


####my.cnf
MySQLサーバの設定ファイルになります。
詳細な設定は後ほど記載するdocker-compose.ymlに記載しているので最小限にしています。

```ruby:my.cnf
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
[client]
default-character-set=utf8mb4
```

`[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci`
文字コードをutf8mb4に設定しています。
`[client]
default-character-set=utf8mb4`
クライアントの文字コードの設定

参考記事
[MySQL(InnoDB) で charset を utf8mb4 にする注意点の現在](https://dev.to/seizans/mysqlinnodb--charset--utf8mb4--1451)
[文字コードを設定する](https://www.dbonline.jp/mysql/myini/index3.html)
[基礎MySQL ~その２~ my.cnf (設定ファイル)](https://qiita.com/yoheiW@github/items/bcbcd11e89bfc7d7f3ff)

####docker-compose.yml
docker-composeの設定ファイル（各コンテナの設定）

```ruby:docker-compose.yml

# docker-composeで使用するバージョンを定義しています。
version: '3'
# アプリケーションを動かすための各要素のこと。servicesの中に、app、db、phpmyadminが子要素として設定されています。
services:
 # laravelを動かすコンテナがここから下に記載されています。
 app:
   #コンテナの名前をここで決めます。
   container_name: laravel_app
   # どのポートを繋ぐかという設定です。ホストの8080番ポートとコンテナの８０番をつないでいる。80番ポートのバーチャルホストは000-default.confにて設定済みです。
   ports:
     - "8000:80"
   # Dockerfileの設定の場所を指定しています。Dockerfileの内容に基づいてビルドします。
   build: ./Docker/App
   # コンテナとホスト側のディレクトリを同期する場所をここで指定しています。ここにlaravelのソースが入ります。
   volumes:
     - ./src:/var/www/html
 # MySQLを動かすコンテナがここから設定されています。
 db:
   #Docker HubからMySQL5.7の公式イメージを引っ張ってくる設定です。
   image: mysql:5.7
   # コンテナ名を指定しています。
   container_name: laravel_db
   # MySQLのコンテナ内の環境変数を指定しています。任意のものを設定してください。
   environment:
     MYSQL_ROOT_PASSWORD: root
     MYSQL_DATABASE: laraveldb
     MYSQL_USER: dbuser
     MYSQL_PASSWORD: dbpass
     TZ: 'Asia/Tokyo'
   # 起動時のコマンドになります。
   command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
   # ディレクトリの同期をしています。ここを書かないとコンテナを閉じたときにデータベースからデータがなくなるので注意してください。詳しくはdocker 永続化などと調べると良いかもです。
   volumes:
     - ./Docker/DB/volume:/var/lib/mysql
     - ./Docker/DB/my.cnf:/etc/mysql/conf.d/my.cnf
   # ホストの13306番ポートとコンテナのなかの3306番ポートとつなげる設定です。
   ports:
     - 13306:3306
 # phpmyadminの設定が書きに記載します。
 phpmyadmin:
   #コンテナ名を決めています。
   container_name: phpmyadmin
   #DockerHubからphpmyadminのイメージを引っ張ってくる設定です。
   image: phpmyadmin/phpmyadmin
   #phpmyadminの環境変数の設定です。MySQLの設定を参照して記載してください。PMA_HOSTSにはservicesのdbを指定しています。
   environment:
    - PMA_ARBITRARY=1
    - PMA_HOSTS=db
    - PMA_USER=root
    - PMA_PASSWORD=root
   ports:
    - 3000:80
```

参考記事
[docker-compose.ymlの書き方について解説してみた](https://qiita.com/yuta-ushijima/items/d3d98177e1b28f736f04)
[DockerでMySQLお試し環境を構築する（ついでにphpMyAdminも）](https://qiita.com/matyahiko2831/items/2d28297a89a9a6a1b0bf)
[Docker で PHP 7.4 と MariaDB 10.5 の LAMP + phpMyAdmin 環境を構築する方法](https://tt-computing.com/docker-php74-mariadb10_5)


##コンテナを立ちあげる

ビルドします。（docker-compose.ymlファイルがあるディレクトリで行ってください）

```
[Mac]$ docker-compose build
      :
      :
     Successfully built c1c2970ecb4b
     Successfully tagged docker_laravel_app:latest
```
などと出力され問題なく終了すれば、以下のコマンドでコンテナを立ち上げます。

```
[Mac]$ docker-compose up -d
```

-dはバックグラウンドでコンテナを立ち上げる場合につけます。
不要であれば外してください。

コンテナが立ち上がっているか確認します。

```
[Mac]$ docker ps
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                                NAMES
e2164a5c2371        docker_laravel_app      "docker-php-entrypoi…"   3 minutes ago       Up 2 minutes        0.0.0.0:8000->80/tcp                 laravel_app
5d80cab0e266        mysql:5.7               "docker-entrypoint.s…"   3 minutes ago       Up 2 minutes        33060/tcp, 0.0.0.0:13306->3306/tcp   laravel_db
ad4786c13249        phpmyadmin/phpmyadmin   "/docker-entrypoint.…"   3 minutes ago       Up 2 minutes        0.0.0.0:3000->80/tcp                 phpmyadmin
```
コンテナの情報が出力されいれば問題ないです。

##laravelのインストール

コンテナの中に入ってlaravelのプロジェクトをインストールします。

docker exec でコンテナの中に入ります。

```
[Mac]$ docker exec -it laravel_app bash
root@e2164a5c2371:/var/www/html#　//左のように表示されていればコンテナの中に入れています。
```

composerを使ってlaravelをインストールします。composerはDockerfileにて設定したようにインストール済みなので以下のコマンドでインストールできます。今回は6系のlaravelをインストールします。私が持っている[技術書](https://www.amazon.co.jp/PHP-E3-83-95-E3-83-AC-E3-83-BC-E3-83-A0-E3-83-AF-E3-83-BC-E3-82-AFLaravel-E5-85-A5-E9-96-80-E7-AC/dp/4798060992/ref=dp_ob_image_bk)がlaravelの６系を使っているので6系でインストールします。（ちょっと時間がかかります。）

```
[コンテナ内]# composer create-project "laravel/laravel=~6.0" --prefer-dist laravelapp
```

最新バージョンをインストールする場合は下記のコマンドを実施

```
[コンテナ内]# composer create-project laravel/laravel --prefer-dist laravelapp
```

コンテナ内の`/var/www/html`とホスト側のsrcディレクトリにlaravelappディレクトリがインストールされていることを確認します。
開発する際は、ホストOS側のsrc/laravelappディレクトリ内のソースコードを編集すれば問題ないです。


docker-compose.ymlで設定したようにホストOSの8000番ポートをコンテナ内の80番ポートに繋がっているので
http://localhost:8000
にアクセスして、laravelのTOPページが出力されれば問題なしです。
![スクリーンショット 2020-11-07 1.04.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663044/5e80043a-6c50-32e9-680c-1e4ed599c415.png)

##DBの設定をし、接続する。
Docker-composeで作成したコンテナはコンテナ名で名前解決をしています。（コンテナ名で通信できます。）
laravelのコンテナから、MySQLのコンテナに接続するには、laravel_dbというホスト名（コンテナ名）の3306ポートにアクセスすれば、MySQLにアクセスできます。
docker-compose.ymlで設定したものを参考にしつつ`src/laravel`ディレクトリないにある.envファイルの中にMySQLの設定箇所があるので以下のように記載します。docker-compose.ymlで設定を変えている場合はそれに合わせてください。

```
DB_CONNECTION=mysql
DB_HOST=laravel_db
DB_PORT=3306
DB_DATABASE=laraveldb
DB_USERNAME=dbuser
DB_PASSWORD=dbpass
```

実際に接続してみます。

```
[Mac]$ docker exec -it laravel_app bash
[コンテナ内]# cd laravel_app
[コンテナ内]# php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.2 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (0.18 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (0.08 seconds)
```

上記のように出力されれば問題なしです。


##phpmyadminに接続する
phpmyadminはブラウザ上でDBの中身をわかりやすく表示や管理が行えるツールです。
詳しくは参考資料をご覧ください。
[SQLの管理に役立つ！phpMyAdminの使い方【初心者向け】](https://techacademy.jp/magazine/12273)
[phpMyAdminの使い方](https://www.dbonline.jp/phpmyadmin/)

下記のURLにアクセスしてphpmyadminが表示されることを確認する。（docker-compose.ymlで3000番ポートに設定済みです）
http://localhost:3000/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663044/dd270ac3-aa13-ace6-7b4f-89a4ec1c21dd.png)

##MySQLサーバに入る。

MySQLのコンテナに入り、MySQLサーバに入ってみます。下記の順番でコマンドを実行してみます。

```
[Mac]$ docker exec -it laravel_db bash
[コンテナ内]root@5d80cab0e266:/# mysql -uroot -p 
Enter password:（docker-compose.ymlで決めたrootユーザのパスワード）
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 17
Server version: 5.7.32 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| laraveldb          |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.02 sec)

mysql> use laraveldb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+---------------------+
| Tables_in_laraveldb |
+---------------------+
| failed_jobs         |
| migrations          |
| password_resets     |
| users               |
+---------------------+
4 rows in set (0.00 sec)

mysql>
```
`mysql -uroot -p `
-uでユーザを指定します。今回はrootユーザで入ります。
-pはパスワードを入力するというオプションです。

`show databases;`
全てのデータベースを出力します。

`use laraveldb;`
laraveldbのデータベースを使うというコマンドです。

`show tables;`
使用中のデータベース（laraveldb）のテーブルを全て出力するというコマンドです。

##最後に
これでlaravelの環境構築は終了であとはガシガシ開発作業を進めていくだけです！！
最後まで読んでいただいてありがとうございました。

参考記事まとめ
　　[名前ベースの仮想ホスト](https://www.adminweb.jp/apache/virtual/index2.html)
　　[一つのApacheサーバーで複数ドメインのサイトを公開する方法](https://dawaan.com/apache-multiple-sites/)
　　[メモ：Apacheの設定ファイル(http.conf)を確認する (1)](https://qiita.com/KoriCori/items/e4fc93482f9b434a92cd)
　　[Apacheのディレクトリを理解しよう](https://kana-linux.info/linux/apache%E3%81%AE%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%82%92%E7%90%86%E8%A7%A3%E3%81%97%E3%82%88%E3%81%86)
　　[UbuntuにてApacheのモジュールを有効化する](https://www.t3a.jp/blog/infrastructure/apache2-mod-add/)
　　[DockerでLaravel+Apache+MySQLの開発環境を構築する](https://note.com/pocke_techblog/n/n8af813848fa0)
　　↑特に参考にさせていただきました。
　　[php.ini ディレクティブのリスト](https://www.php.net/manual/ja/ini.list.php)
　　[php.ini設定で設定可能な項目について](https://www.xserver.ne.jp/manual/man_server_phpini_setting_item.php)
　　[php.iniの編集](https://qiita.com/hikotaro_san/items/0aab2a53726674c50868)
　　[MySQL(InnoDB) で charset を utf8mb4 にする注意点の現在](https://dev.to/seizans/mysqlinnodb--charset--utf8mb4--1451)
　　[文字コードを設定する](https://www.dbonline.jp/mysql/myini/index3.html)
　　[基礎MySQL ~その２~ my.cnf (設定ファイル)](https://qiita.com/yoheiW@github/items/bcbcd11e89bfc7d7f3ff)
　　[docker-compose.ymlの書き方について解説してみた](https://qiita.com/yuta-ushijima/items/d3d98177e1b28f736f04)
　　[DockerでMySQLお試し環境を構築する（ついでにphpMyAdminも）](https://qiita.com/matyahiko2831/items/2d28297a89a9a6a1b0bf)
　　[Docker で PHP 7.4 と MariaDB 10.5 の LAMP + phpMyAdmin 環境を構築する方法](https://tt-computing.com/docker-php74-mariadb10_5)
　　[SQLの管理に役立つ！phpMyAdminの使い方【初心者向け】](https://techacademy.jp/magazine/12273)
　　[phpMyAdminの使い方](https://www.dbonline.jp/phpmyadmin/)