dockerに苦労した話

# 今回の教材
[Laravelでテスト駆動開発を学ぼう！](https://www.techpit.jp/courses/92)

# 課題に取り組む前にLaravelのMigrateで沼にハマる
## Reset
docker desktop のアンインストール
スタート -> 設定 -> アプリ（ふつーに消えてくれる）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94562/aab44340-803a-9af5-8b81-adf328c3831e.png)
explorerで普通に消そうとするとブルースクリーンが出て再起動になり、永遠に消せない（この時代にブルースクリーンなんて久しぶりに見たわ...）。powershell管理者モードでバチンと消すしか無いらしい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94562/b8e2c71b-8b2e-cfe3-1ef6-af13c899a474.png)

```powershell:learning-laravel-tddというディレクトリが基準
PS C:\WINDOWS\system32> cd D:\OneDrive\dev
PS D:\OneDrive\dev> rm -Force learning-laravel-tdd
```

## Docker Desktop for Windows のインストール
https://hub.docker.com/editions/community/docker-ce-desktop-windows/
インストール自体はすんなりいく

## Docker 用 git リポジトリのクローン
```console:OneDrive\dev>
$ mkdir learning-laravel-tdd
$ cd learning-laravel-tdd
$ git clone https://github.com/nunulk/learning-laravel-tdd-docker docker
$ mkdir app
```

### 現在の状態
```
learning-laravel-tdd
├── app
└── docker
```

```console:Dockerを起動してからやってね
$ cd docker
$ cp .env.example .env
$ docker-compose up -d 
```

## Portのかぶりを解決する（DB_PORTを3308に）
僕の場合は 3306 がかぶっていることがわかった（普段pythonで使ってるから）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94562/3194ecb2-8bf7-c9f6-334f-9d87d08186c8.png)

```diff:learning-laravel-tdd\docker\.env
COMPOSE_PROJECT_NAME=learning-laravel-tdd
APP_PATH=../app
TZ=Asia/Tokyo
WEB_PORT=80
- DB_PORT=3306
+ DB_PORT=3308
DB_DATABASE=learning_laravel_tdd
DB_USERNAME=root
DB_PASSWORD=root
DB_TESTING_DATABASE=learning_laravel_tdd_testing
DB_TESTING_PORT=3307
DB_TESTING_USERNAME=root
DB_TESTING_PASSWORD=root
```

するとDockerのコントロールパネルでstartしたときに全部つく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94562/4042047e-78ac-ee92-897d-5c3b865f81e4.png)

## 動作確認
以下のコマンドを実行して、すべてのコンテナが起動しているかどうか確認

```console:learning-laravel-tdd\docker>
$ docker-compose ps
              Name                             Command              State                 Ports
-------------------------------------------------------------------------------------------------------------
learning-laravel-tdd_app_1          docker-php-entrypoint php-fpm   Up      9000/tcp
learning-laravel-tdd_db-testing_1   docker-entrypoint.sh mysqld     Up      0.0.0.0:3307->3306/tcp, 33060/tcp
learning-laravel-tdd_db_1           docker-entrypoint.sh mysqld     Up      0.0.0.0:3308->3306/tcp, 33060/tcp
learning-laravel-tdd_web_1          nginx -g daemon off;            Up      0.0.0.0:80->80/tcp
```

## アプリケーションの初期化
```console:learning-laravel-tdd\docker>
$ docker exec -it learning-laravel-tdd_app_1 ash
# composer create-project --prefer-dist "laravel/laravel=7.*" .
```

##
```diff:learning-laravel-tdd\app\.env
# 中略

LOG_CHANNEL=stack


- DB_CONNECTION=mysql
- DB_HOST=127.0.0.1
- DB_PORT=3306
- DB_DATABASE=laravel
- DB_USERNAME=root
- DB_PASSWORD=
+ DB_CONNECTION=mysql
+ DB_HOST=db
+ DB_PORT=3306
+ DB_DATABASE=learning_laravel_tdd
+ DB_USERNAME=root
+ DB_PASSWORD=root
+ DB_TESTING_HOST=db-testing
+ DB_TESTING_PORT=3306
+ DB_TESTING_DATABASE=learning_laravel_tdd_testing
+ DB_TESTING_USERNAME=root
+ DB_TESTING_PASSWORD=root

BROADCAST_DRIVER=log

# 中略
```

```diff:learning-laravel-tdd\app\config\database.php
        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
-           'port' => env('DB_PORT', '3306'),
+           'port' => env('DB_PORT', '3308'),
            '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'),
            ]) : [],
        ],


+       'mysql_testing' => [
+           'driver' => 'mysql',
+           'host' => env('DB_TESTING_HOST', '127.0.0.1'),
+           'port' => env('DB_TESTING_PORT', '3307'),
+           'database' => env('DB_TESTING_DATABASE', 'forge'),
+           'username' => env('DB_TESTING_USERNAME', 'forge'),
+           'password' => env('DB_TESTING_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'),
+           ]) : [],
+        ],
 
         'pgsql' => [
             'driver' => 'pgsql',
             'url' => env('DATABASE_URL'),
```

```diff:learning-laravel-tdd\app\phpunit.xml
        <server name="CACHE_DRIVER" value="array"/>
-       <!-- <server name="DB_CONNECTION" value="sqlite"/> -->
-       <!-- <server name="DB_DATABASE" value=":memory:"/> -->
+       <server name="DB_CONNECTION" value="mysql_testing"/>
+       <server name="DB_DATABASE" value="learning_laravel_tdd_testing"/>       
        <server name="MAIL_MAILER" value="array"/>
```

## Models ディレクトリの作成と User.php の移動
Laravel は、デフォルトでは Model クラスを artisan コマンドで生成すると app ディレクトリ直下に生成しますが、本教材では、Models ディレクトリを作って、そこに配置していきます。インストールで自動的に作られる User.php をあらかじめ Models ディレクトリに移しておきましょう。

まずは以下のコマンドを実行してディレクトリを作成します（コンテナ側でもホスト側でもどちらでも大丈夫です）。

```console:learning-laravel-tdd\app
# mkdir app/Models
```
続いて、app/User.php を app/Models 以下へ移動し、名前空間を変更します。

```php:learning-laravel-tdd\app\Models\User.php
namespace App\Models;
```
User クラスを参照している箇所の名前空間もあわせて変更します。

変更するのは以下の2つのファイルです。

```diff:learning-laravel-tdd\app\config\auth.php
'providers' => [
    'users' => [
        'driver' => 'eloquent',
-       'model' => App\User::class,
+       'model' => App\Models\User::class,
    ],
```
```diff:learning-laravel-tdd\app\database\factories\UserFactory.php
- use App\User;
+ use App\Models\User;
```

## config is ignored
`learning-laravel-tdd\docker\db\my.cnf` を読み取り専用にする
Windowsだけの問題らしい
>mysqld: [Warning] World-writable config file '/etc/mysql/my.cnf' is ignored. がでる
[[Docker+Windows]mysqlのdockerイメージがmy.cnfのマウントのエラーで起動しない時の対処法](https://qiita.com/rabbitbeef/items/14433a2c0a6f85c3b476)

## アプリケーションの確認
最後に、アプリケーションが動作するか確認するため、コンテナ内で以下のコマンドを実行してください。

```console
/app # php artisan migrate
```

ちなみに未解決事件と化した。だれかだすけてよぉ～