DockerでLaravel環境を構築する

下記の記事を参考にDockerでLaravel＋MySQLの環境構築をしました。
途中のエラーでハマった点も合わせてメモしておきます。

参考：[https://www.engilaboo.com/laravel-docker/](https://www.engilaboo.com/laravel-docker/)

**最終的なディレクトリ構成**

app
└app
└docker
　　└Dockerfile
└docker-compose.yaml

**Dockerfileを作成**

```docker
FROM php:8.0-apache
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN apt-get update && apt-get install -y \
    git \
    && docker-php-ext-install pdo_mysql
    
RUN sed -i 's!/var/www/html!/var/www/app/public!g' /etc/apache2/sites-available/000-default.conf
```

**docker-compose.yamlの作成**

```yaml
version: '3'
services:
  app:
    build: ./docker
    ports:
      - 80:80
    volumes:
      - ./app:/var/www/app
    working_dir: /var/www/app
  db:
    image: mysql:8.0
    ports:
      - 3306:3306
    environment:
      MYSQL_DATABASE: database
      MYSQL_USER: user
      MYSQL_PASSWORD: pass
```

**Laravelのインストール**

```bash
# コンテナの立ち上げ
docker-compose up -d

# appコンテナに入る
docker-compose exec app bash

# var/www/appの中でコマンドを実行
composer create-project laravel/laravel .
```

**画面の表示確認**

[http://localhost:80](http://localhost/)

**データベース接続確認**

```bash
# Laravel内の.envファイル
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=database
DB_USERNAME=user
DB_PASSWORD=pass
```

**appコンテナ内でコマンドを実行**

```bash
php artisan migrate
```

**まさかのエラーが起こる**

```bash
Illuminate\Database\QueryException 

  SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known (SQL: select * from information_schema.tables where table_schema = database and table_name = migrations and table_type = 'BASE TABLE')

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:716
    712▕         // If an exception occurs when attempting to run a query, we'll format the error
    713▕         // message to include the bindings with SQL, which will make this exception a
    714▕         // lot more helpful to the developer instead of just the database's errors.
    715▕         catch (Exception $e) {
  ➜ 716▕             throw new QueryException(
    717▕                 $query, $this->prepareBindings($bindings), $e
    718▕             );
    719▕         }
    720▕     }

      +36 vendor frames 
  37  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
```

通常は.envで書いたDBのホスト名とDockerのDBサービス名が不一致なら出るエラーらしいが、今回は一致していた。

docker-compose ps でコンテナの様子を見てみる。(DB落ちてる・・・。)

```bash
Name                     Command               State          Ports       
--------------------------------------------------------------------------------
laravel-app_app_1   docker-php-entrypoint apac ...   Up       0.0.0.0:80->80/tcp
laravel-app_db_1    docker-entrypoint.sh mysqld      Exit 1
```

docker-compose logs でログを見てみる

```bash
Attaching to laravel-app_app_1, laravel-app_db_1
db_1   | 2022-03-24 14:28:39+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
db_1   | 2022-03-24 14:28:39+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
db_1   | 2022-03-24 14:28:39+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
db_1   | 2022-03-24 14:28:39+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
db_1   |     You need to specify one of the following:
db_1   |     - MYSQL_ROOT_PASSWORD
db_1   |     - MYSQL_ALLOW_EMPTY_PASSWORD
db_1   |     - MYSQL_RANDOM_ROOT_PASSWORD
app_1  | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.21.0.2. Set the 'ServerName' directive globally to suppress this message
app_1  | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.21.0.2. Set the 'ServerName' directive globally to suppress this message
app_1  | [Thu Mar 24 14:28:41.150363 2022] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.52 (Debian) PHP/8.0.17 configured -- resuming normal operations
app_1  | [Thu Mar 24 14:28:41.150570 2022] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
app_1  | 172.21.0.1 - - [24/Mar/2022:14:28:46 +0000] "GET / HTTP/1.1" 200 6371 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36"
app_1  | 172.21.0.1 - - [24/Mar/2022:14:28:49 +0000] "GET /favicon.ico HTTP/1.1" 304 246 "http://localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36"
app_1  | 172.21.0.1 - - [24/Mar/2022:14:29:38 +0000] "-" 408 0 "-" "-"
```

なんかエラー出てる・・。

```bash
[ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
db_1   |     You need to specify one of the following:
```

ググったところ、rootのパスワードを設定してあげないといけないことが分かった。

[https://penpen-dev.com/blog/docker-composeでmysqlコンテナを作ろうとしたら→-database-is-uninitialized-and-password-option-is-not-s/](https://penpen-dev.com/blog/docker-compose%E3%81%A7mysql%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%82%92%E4%BD%9C%E3%82%8D%E3%81%86%E3%81%A8%E3%81%97%E3%81%9F%E3%82%89%E2%86%92-database-is-uninitialized-and-password-option-is-not-s/)

**docker-compose.yaml に MYSQL_ROOT_PASSWORD: pass を追記**

```bash
version: '3'
services:
  app:
    build: ./docker
    ports:
      - 80:80
    volumes:
      - ./app:/var/www/app
    working_dir: /var/www/app
  db:
    image: mysql:8.0
    ports:
      - 3306:3306
    environment:
      MYSQL_DATABASE: database
      MYSQL_USER: user
      MYSQL_PASSWORD: pass
      MYSQL_ROOT_PASSWORD: pass
```

再度、トライ

```bash
docker-compose up -d
docker-compose ps

# 両方立ち上がった！！
Name                     Command               State                 Ports              
----------------------------------------------------------------------------------------------
laravel-app_app_1   docker-php-entrypoint apac ...   Up      0.0.0.0:80->80/tcp               
laravel-app_db_1    docker-entrypoint.sh mysqld      Up      0.0.0.0:3306->3306/tcp, 33060/tcp
```

```bash
docker-compose exec app bash
```

```bash
php artisan migrate

# いけた！！
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (65.69ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (56.84ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (61.45ms)
Migrating: 2019_12_14_000001_create_personal_access_tokens_table
Migrated:  2019_12_14_000001_create_personal_access_tokens_table (92.64ms)
```

完了！！