Docker ComposeでLaravel開発環境を構築その陸

前回、HTTPSやRedisを導入し、段々オールインワンっぽくなって来た。
[Docker ComposeでLaravel開発環境を構築その伍](https://qiita.com/_bobtabo_/items/e76a14bd7ed65b5e34b1)

更にオールインワン化を目指しつつ、そろそろPHP8を使いたいし、Xdebug3にしたい。
ついでに、MySQLのレプリケーションも欲しくなったので修正する。

# マシンスペック
* Mac mini 2018
* macOS Catalina（10.15.x）
* Intel Core-i7 3.2GHz 6コア
* メモリ 32GB
* SSD 512GB

# Docker環境
* Nginx 最新版
* PHP（PHP-FPM） 8.x
* Xdebug 3.x
* MySQL 8.x
* Composer 2.x
* Laravel 8.x
* Redis 最新版
* MailHog 最新版
* phpMyAdmin 最新版
* MongoDB 最新版
* mongo-express 最新版
* Redmon 最新版

# やること
* PHP8が欲しい
* XDebug3が欲しい
* レプリケーションが欲しい
* オールインワンを目指す

# 補足
各環境を行ったり来たりするので、下記のように記載します。

```
[Mac]$ MacのターミナルでMac内の作業
[PHP]$ MacのターミナルからPHPコンテナに接続して作業
[SQL]# MacのターミナルからMySQLコンテナに接続して作業
```

# 追加・変更あれこれ

### PHP 8.x

https://github.com/bobtabo/docker4/blob/master/php/Dockerfile

下記に変更する。

```dockerfile:php/Dockerfile
FROM php:8-fpm
```

### Xdebug 3.x

3.x にすると設定ファイルが変わるので、2.x に固定してたのを修正する。

https://github.com/bobtabo/docker4/blob/master/php/Dockerfile

```dockerfile:php/Dockerfile
RUN pecl install xdebug-2.9.8
↓
RUN pecl install xdebug
```

https://github.com/bobtabo/docker4/blob/master/php/xdebug.ini

下記に変更する。

```ini:php/xdebug.ini
xdebug.mode=debug,develop
xdebug.discover_client_host = 1
xdebug.client_host=host.docker.internal
xdebug.client_port=9001
xdebug.idekey=PHPSTORM
```

※参考
[Xdebug3.0.0がリリースされたので、ver2からの雑な設定コンバート](https://qiita.com/naoyukik/items/ef83fd9f59228694556d)
[Xdebug 2 から 3 へのアップグレード](https://xdebug.org/docs/upgrade_guide/ja)

### phpMyAdmin

いつもPhpStormからDB見てるけど、一応入れておく。

```yaml:docker-compose.yml
phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: ${PMA_CONTAINER}
    depends_on:
      - mysql
    environment:
      - PMA_ARBITRARY=${PMA_ARBITRARY}
      - PMA_HOSTS=${PMA_HOSTS}
      - PMA_USER=${PMA_USER}
      - PMA_PASSWORD=${PMA_PASSWORD}
    ports:
      - "${PMA_PORT}:80"
    volumes:
      - ./data/phpmyadmin/sessions:/sessions
```

### MongoDB

もしかして使う機会あるかもなので入れておく。

```yaml:docker-compose.yml
mongo:
  image: mongo
  container_name: ${MONGO_CONTAINER}
  environment:
    MONGO_INITDB_ROOT_USERNAME: ${MONGO_USERNAME}
    MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD}
  ports:
    - "${MONGO_PORT}:27017"
  volumes:
    - ./data/mongo:/data/db
```

### mongo-express

MongoDBを可視化できるらしいので入れておく。

```yaml:docker-compose.yml
mongo-express:
  image: mongo-express
  container_name: ${MONGO_EX_CONTAINER}
  ports:
    - "${MONGO_EX_PORT}:8081"
  environment:
    ME_CONFIG_BASICAUTH_USERNAME: ${MONGO_EX_USERNAME}
    ME_CONFIG_BASICAUTH_PASSWORD: ${MONGO_EX_PASSWORD}
    ME_CONFIG_MONGODB_PORT: ${MONGO_PORT}
    ME_CONFIG_MONGODB_ADMINUSERNAME: ${MONGO_EX_ADMINUSERNAME}
    ME_CONFIG_MONGODB_ADMINPASSWORD: ${MONGO_EX_ADMINPASSWORD}
  depends_on:
    - mongo
```

### Redmon

phpRedisAdminはキーが増えると遅いらしいので、Redmonを導入。

```yaml:docker-compose.yml
redmon:
  image: vieux/redmon
  container_name: ${REDMON_CONTAINER}
  links:
    - redis:redis
  ports:
    - "${REDMON_PORT}:4567"
  command: -r redis://redis:6379
```

# MySQLのレプリケーション

### .env.exampleに追加

```ini:.env.example
MYSQL_SLAVE_CONTAINER=mysql-slave
MYSQL_SLAVE_PORT=13306
```

### Master＆Slave設定を作成

[コチラ](https://github.com/raahii/docker-mysql-master-slave)から必要ファイルを丸パク＆編集して配置。

![スクリーンショット 2021-02-26 2.06.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111551/932e6b24-5c8c-c602-ed30-6ca9ec5096da.png)

### docker-compose.ymlを修正

```yaml:docker-compose.yml
version: '3.8'
〜 略 〜
  mysql:
〜 略 〜
    volumes:
      - ./mysql/master/my.cnf:/etc/mysql/my.cnf
      - ./data/mysql:/var/lib/mysql
      - ./mysql/master/init.sql:/docker-entrypoint-initdb.d/init.sql

  mysql-slave:
    image: mysql:8
    container_name: ${MYSQL_SLAVE_CONTAINER}
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_ALLOW_EMPTY_PASSWORD: 1
      TZ: "Asia/Tokyo"
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    ports:
      - "${MYSQL_SLAVE_PORT}:3306"
    depends_on:
      - mysql
    tmpfs:
      - /var/lib/mysql
    volumes:
      - ./mysql/slave/my.cnf:/etc/mysql/my.cnf
      - ./mysql/slave/init.sql:/docker-entrypoint-initdb.d/init.sql
〜 略 〜
```

※参考
[docker-composeでMaster/Slave構成のMySQLを手に入れる](https://qiita.com/takyam/items/f13bc4a1db0433ffb958)
[docker-composeでお手軽mysqlのmaster-slave構成](https://www.te-nu.com/entry/2018/07/01/181714)
[docker-mysql-master-slave/docker-compose.yml at master · raahii/docker-mysql-master-slave](https://github.com/raahii/docker-mysql-master-slave)

### Laravelのデータベース設定を変更

接続設定を変更する。

```ini:src/laravel/.env.example
DB_CONNECTION=mysql
DB_MASTER_HOST=mysql
DB_MASTER_PORT=3306
DB_SLAVE_HOST=mysql
DB_SLAVE_PORT=3306
DB_DATABASE=hoge
DB_USERNAME=fuga
DB_PASSWORD="docker#DOCKER1234"
```

データベース設定を変更する。

```config:src/laravel/config/database.php
<?php

return [
〜 略 〜
        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'read' => [
                'host' => env('DB_SLAVE_HOST', '127.0.0.1'),
                'port' => env('DB_SLAVE_PORT', '3306'),
            ],
            'write' => [
                'host' => env('DB_MASTER_HOST', '127.0.0.1'),
                'port' => env('DB_MASTER_PORT', '3306'),
            ],
            'sticky' => true,
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],
〜 略 〜
];
```

完成！！
https://github.com/bobtabo/docker5

# 使い方

コンテナ定義をクローンして起動する。

```terminal
[Mac]$ cd <任意のディレクトリ>
[Mac]$ git clone https://github.com/bobtabo/docker5.git docker
[Mac]$ cd docker
[Mac]$ cp -p .env.example .env
[Mac]$ docker-compose up -d
・・・
Creating redis         ... done
Creating mailhog       ... done
Creating mysql-slave   ... done
Creating mysql         ... done
Creating mongo         ... done
Creating redmon        ... done
Creating mongo-express ... done
Creating php           ... done
Creating phpMyAdmin    ... done
Creating nginx         ... done
```

コンテナ起動を確認する。

```terminal
[Mac]$ docker-compose ps

    Name                   Command               State                    Ports                  
-------------------------------------------------------------------------------------------------
mailhog         MailHog                          Up      1025/tcp, 0.0.0.0:8025->8025/tcp        
mongo           docker-entrypoint.sh mongod      Up      0.0.0.0:27017->27017/tcp                
mongo-express   tini -- /docker-entrypoint ...   Up      0.0.0.0:8081->8081/tcp                  
mysql           docker-entrypoint.sh mysql ...   Up      0.0.0.0:3306->3306/tcp, 33060/tcp       
mysql-slave     docker-entrypoint.sh mysql ...   Up      0.0.0.0:13306->3306/tcp, 33060/tcp      
nginx           /docker-entrypoint.sh ngin ...   Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
php             docker-php-entrypoint php-fpm    Up      0.0.0.0:9001->9000/tcp                  
phpMyAdmin      /docker-entrypoint.sh apac ...   Up      0.0.0.0:8080->80/tcp                    
redis           docker-entrypoint.sh redis ...   Up      0.0.0.0:6379->6379/tcp                  
redmon          redmon -r redis://redis:6379     Up      0.0.0.0:4567->4567/tcp
```
Stateが全てUpならOK、Exit 1だとエラー。
<font color="blue">エラー時は下記コマンドでログを見る。</font>

```terminal
[Mac]$ docker-compose logs
```

MySQLコンテナに入り、レプリケーション状態を確認する。

```terminal
[Mac]$ docker-compose exec mysql-slave bash
[SQL]# mysql -u root -p
Enter password:docker#DOCKER1234
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
〜 略 〜
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
〜 略 〜
mysql> quit
[SQL]# exit
```

PHPコンテナに入り、Laravelを設定する。

```terminal
[Mac]$ docker-compose exec --user 1000 php bash

[PHP]$ pwd
/home/docker

[PHP]$ cd laravel
[PHP]$ composer install
[PHP]$ chmod -R 777 storage
[PHP]$ chmod -R 777 bootstrap/cache
[PHP]$ cp -p .env.example .env
[PHP]$ php artisan key:generate
[PHP]$ chmod 755 bin/clear-laravel.sh
[PHP]$ bin/clear-laravel.sh
[PHP]$ php artisan migrate:fresh --seed
```

### hosts編集
```configuration
[Mac]$ sudo vi /private/etc/hosts
★下記を点線内を追記
---
127.0.0.1 laravel.local
---
:wq
```

### ブラウザで動作確認

http://laravel.local/
https://laravel.local/

<font color="blue">※httpsはSafariだと簡単に見れる（Chromeだと面倒）</font>

![スクリーンショット 2021-01-21 23.02.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111551/020058fa-ab24-7bda-668a-bb9832c5892c.png)

http://laravel.local:8025/
![スクリーンショット 2021-02-11 15.50.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111551/4e146315-6822-fc67-d75f-3d6d2c02c01c.png)

http://laravel.local:8080/
![スクリーンショット 2021-02-26 2.04.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111551/6bfd5964-6345-d37a-d7e1-b15676df69d2.png)


http://laravel.local:8081/
![スクリーンショット 2021-02-26 0.34.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111551/666559ff-74e7-fd25-a419-ef19c84f5102.png)

http://laravel.local:4567/
![スクリーンショット 2021-02-26 0.35.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111551/ba5e4fa2-62e8-7fe5-ec9a-a6520cff0e1e.png)

### コンテナ削除

```terminal
[Mac]$ docker-compose down --rmi all --volumes
```

※参考
[《滅びの呪文》Docker Composeで作ったコンテナ、イメージ、ボリューム、ネットワークを一括完全消去する便利コマンド](https://qiita.com/suin/items/19d65e191b96a0079417)