DockerでLaravelの環境を作ってみる

# はじめに

転職先でLaravelを使うことになるんですが、どうせならDockerでLaravelの環境作ってみたいなと、「Docker&仮想サーバー完全入門」を読んでとりあえずDockerのコマンドをひたすら叩いた。
これ読んだだけでは自分で環境作ったりするのには十分ではないので、本を参考にしつつ先人の知恵も拝借しながら、Laravelの環境を構築する。

失敗した内容も記載しているので長いのはご愛敬。

# 構成

laravel
├src
├compose.yaml
└Dockerfile

```yaml:compose.yaml
services:
  db:
    image: mariadb:10.1
    environment:
      MARIADB_ROOT_PASSWORD: rootpass
      MARIADB_DATABASE: testdb
      MARIADB_USER: testuser
      MARIADB_PASSWORD: testpass
    volumes:
      - db-data:/var/lib/mysql
  phpmyadmin:
    image: phpmyadmin:5.2
    depends_on:
      - db
    environment:
      PMA_HOST: db
      PMA_USER: testuser
      PMA_PASSWORD: testpass
    ports:
      - "8080:80"
    volumes:
      - phpmyadmin-data:/sessions
  php:
    build: .
    depends_on:
      - db
    ports:
      - "8082:80"
    volumes:
      - ./src:/var/www/html
volumes:
  db-data:
  phpmyadmin-data:
```

```Dockerfile:Dockerfile
FROM php:7.2-apache

RUN apt-get update

RUN apt-get install -y libonig-dev

# mariadbにアクセスするためにPDOをインストール
RUN docker-php-ext-install pdo_mysql

# composerのインストール
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer
```

## Laravelプロジェクトの作成(1回目エラー)

```powershell
PS C:\Server\docker\laravel> docker compose run --rm php composer create-project laravel/laravel laravel7-project "7.*"
[+] Running 14/14
 ✔ db 13 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                                                        31.5s
   ✔ 01bf7da0a88c Pull complete                                                                                                                                                                               10.7s
   ✔ f3b4a5f15c7a Pull complete                                                                                                                                                                               10.7s
   ✔ 57ffbe87baa1 Pull complete                                                                                                                                                                               10.8s
   ✔ 7ac3ea3a19e9 Pull complete                                                                                                                                                                               10.8s
   ✔ b89d9d23853d Pull complete                                                                                                                                                                               10.9s
   ✔ 6512bf94537d Pull complete                                                                                                                                                                               11.0s
   ✔ d75afd385b71 Pull complete                                                                                                                                                                               11.0s
   ✔ ab1935952eac Pull complete                                                                                                                                                                               11.1s
   ✔ 209bb6034896 Pull complete                                                                                                                                                                               11.2s
   ✔ aa325c613ddb Pull complete                                                                                                                                                                               11.2s
   ✔ 050a67aa09df Pull complete                                                                                                                                                                               27.8s
   ✔ bdb7d28d54b6 Pull complete                                                                                                                                                                               27.9s
   ✔ 0bc74f023b50 Pull complete                                                                                                                                                                               27.9s
[+] Running 2/2
 ✔ Network laravel_default  Created                                                                                                                                                                            0.0s
 ✔ Container laravel-db-1   Created                                                                                                                                                                            0.2s
[+] Running 1/1
 ✔ Container laravel-db-1  Started                                                                                                                                                                             0.4s
[+] Building 2.0s (9/9) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                                                           0.0s
 => => transferring dockerfile: 32B                                                                                                                                                                            0.0s
 => [internal] load .dockerignore                                                                                                                                                                              0.0s
 => => transferring context: 2B                                                                                                                                                                                0.0s
 => [internal] load metadata for docker.io/library/php:7.2-apache                                                                                                                                              1.9s
 => [1/5] FROM docker.io/library/php:7.2-apache@sha256:4dc0f0115acf8c2f0df69295ae822e49f5ad5fe849725847f15aa0e5802b55f8                                                                                        0.0s
 => CACHED [2/5] RUN apt-get update                                                                                                                                                                            0.0s
 => CACHED [3/5] RUN apt-get install -y libonig-dev                                                                                                                                                            0.0s
 => CACHED [4/5] RUN docker-php-ext-install pdo_mysql                                                                                                                                                          0.0s
 => CACHED [5/5] RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer                                                                           0.0s
 => exporting to image                                                                                                                                                                                         0.0s
 => => exporting layers                                                                                                                                                                                        0.0s
 => => writing image sha256:d523bb1c2f69a3aaf16495da0c57beb243bb174b6b3fd24fdd24b934d7433881                                                                                                                   0.0s
 => => naming to docker.io/library/laravel-php                                                                                                                                                                 0.0s
Creating a "laravel/laravel" project at "./laravel7-project"
Info from https://repo.packagist.org: #StandWithUkraine
Installing laravel/laravel (v7.30.1)
    Failed to download laravel/laravel from dist: The zip extension and unzip/7z commands are both missing, skipping.
Your command-line PHP is using multiple ini files. Run `php --ini` to show them.
    Now trying to download from source

In GitDownloader.php line 82:

  git was not found in your PATH, skipping source download


create-project [-s|--stability STABILITY] [--prefer-source] [--prefer-dist] [--prefer-install PREFER-INSTALL] [--repository REPOSITORY] [--repository-url REPOSITORY-URL] [--add-repository] [--dev] [--no-dev] [--no-custom-installers] [--no-scripts] [--no-progress] [--no-secure-http] [--keep-vcs] [--remove-vcs] [--no-install] [--no-audit] [--audit-format AUDIT-FORMAT] [--ignore-platform-req IGNORE-PLATFORM-REQ] [--ignore-platform-reqs] [--ask] [--] [<package> [<directory> [<version>]]]
```

以下のエラーに対応する必要がありそう。
```
Failed to download laravel/laravel from dist: The zip extension and unzip/7z commands are both missing, skipping.
```

これを解決するには、php.iniを用意する必要があるようだ。
とりあえず、docker compose up -dで起動して、php.iniを確認。
存在しないので、Dopckerfileを修正。
しかし、php.iniにextension=zipがないので、ZIP拡張も入れるようにする。

```Dockerfile:Dockerfile
FROM php:7.2-apache

RUN apt-get update

RUN apt-get install -y libonig-dev

# mariadbにアクセスするためにPDOをインストール
RUN docker-php-ext-install pdo_mysql

# Zipを扱うためにzlib-devとZIP拡張をインストール
RUN apt-get install -y zlib1g-dev

RUN docker-php-ext-install zip

# composerのインストール
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer

RUN cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini
```

## Laravelプロジェクトの作成(2回目エラー)

Dockerfileを直したので、まずはbuild

```powershell
PS C:\Server\docker\laravel> docker compose build
[+] Building 26.5s (12/12) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                                                           0.0s
 => => transferring dockerfile: 550B                                                                                                                                                                           0.0s
 => [internal] load .dockerignore                                                                                                                                                                              0.0s
 => => transferring context: 2B                                                                                                                                                                                0.0s
 => [internal] load metadata for docker.io/library/php:7.2-apache                                                                                                                                              1.8s
 => [1/8] FROM docker.io/library/php:7.2-apache@sha256:4dc0f0115acf8c2f0df69295ae822e49f5ad5fe849725847f15aa0e5802b55f8                                                                                        0.0s
 => CACHED [2/8] RUN apt-get update                                                                                                                                                                            0.0s
 => CACHED [3/8] RUN apt-get install -y libonig-dev                                                                                                                                                            0.0s
 => CACHED [4/8] RUN docker-php-ext-install pdo_mysql                                                                                                                                                          0.0s
 => [5/8] RUN apt-get install -y zlib1g-dev                                                                                                                                                                    1.7s
 => [6/8] RUN docker-php-ext-install zip                                                                                                                                                                      15.1s
 => [7/8] RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer                                                                                  7.2s
 => [8/8] RUN cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini                                                                                                                             0.5s
 => exporting to image                                                                                                                                                                                         0.1s
 => => exporting layers                                                                                                                                                                                        0.1s
 => => writing image sha256:4b671e1e7644abdda5eb9af773f36a8aa2f8b2b8869e6fc2d3d54b3f960de7c5                                                                                                                   0.0s
 => => naming to docker.io/library/laravel-php
```

次にLaravelプロジェクトを作成。

```powershell
PS C:\Server\docker\laravel> docker compose run --rm php composer create-project laravel/laravel laravel7-project "7.*"
[+] Running 2/2
 ✔ Network laravel_default  Created                                                                                                                                                                            0.0s
 ✔ Container laravel-db-1   Created                                                                                                                                                                            0.1s
[+] Running 1/1
 ✔ Container laravel-db-1  Started                                                                                                                                                                             0.4s
Creating a "laravel/laravel" project at "./laravel7-project"
Info from https://repo.packagist.org: #StandWithUkraine
Installing laravel/laravel (v7.30.1)
As there is no 'unzip' nor '7z' command installed zip files are being unpacked using the PHP zip extension.
This may cause invalid reports of corrupted archives. Besides, any UNIX permissions (e.g. executable) defined in the archives will be lost.
Installing 'unzip' or '7z' (21.01+) may remediate them.
  - Downloading laravel/laravel (v7.30.1)
  - Installing laravel/laravel (v7.30.1): Extracting archive
Created project in /var/www/html/laravel7-project
> @php -r "file_exists('.env') || copy('.env.example', '.env');"
Loading composer repositories with package information
Updating dependencies
Lock file operations: 94 installs, 0 updates, 0 removals
  - Locking asm89/stack-cors (v2.1.1)
  - Locking brick/math (0.9.3)
  - Locking doctrine/inflector (2.0.6)
・・・省略・・・
  - Locking tijsverkoyen/css-to-inline-styles (2.2.6)
  - Locking vlucas/phpdotenv (v4.3.0)
  - Locking voku/portable-ascii (1.6.1)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 94 installs, 0 updates, 0 removals
  - Downloading doctrine/inflector (2.0.6)
  - Downloading doctrine/lexer (1.2.3)
  - Downloading dragonmantank/cron-expression (v2.3.1)
・・・省略・・・
  - Downloading myclabs/deep-copy (1.11.1)
  - Downloading doctrine/instantiator (1.5.0)
  - Downloading phpunit/phpunit (8.5.33)
  - Installing doctrine/inflector (2.0.6): Extracting archive
  - Installing doctrine/lexer (1.2.3): Extracting archive
  - Installing dragonmantank/cron-expression (v2.3.1): Extracting archive
・・・省略・・・
  - Installing myclabs/deep-copy (1.11.1): Extracting archive
  - Installing doctrine/instantiator (1.5.0): Extracting archive
  - Installing phpunit/phpunit (8.5.33): Extracting archive
75 package suggestions were added by new dependencies, use `composer suggest` to see details.
Package fruitcake/laravel-cors is abandoned, you should avoid using it. No replacement was suggested.
Package swiftmailer/swiftmailer is abandoned, you should avoid using it. Use symfony/mailer instead.
Package phpunit/php-token-stream is abandoned, you should avoid using it. No replacement was suggested.
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: facade/ignition
Discovered Package: fideloper/proxy
Discovered Package: fruitcake/laravel-cors
Discovered Package: laravel/tinker
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
69 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found
> @php artisan key:generate --ansi
Application key set successfully.
```

なにやら警告が出たが、成功した模様。

```
As there is no 'unzip' nor '7z' command installed zip files are being unpacked using the PHP zip extension.
This may cause invalid reports of corrupted archives. Besides, any UNIX permissions (e.g. executable) defined in the archives will be lost.
Installing 'unzip' or '7z' (21.01+) may remediate them.
```
これはunzipまたは7zが入ってないから、PHPのzip拡張で解凍するよ、問題があったらunzipか7zをインストールすると解決するよという警告。

```
Package fruitcake/laravel-cors is abandoned, you should avoid using it. No replacement was suggested.
Package swiftmailer/swiftmailer is abandoned, you should avoid using it. Use symfony/mailer instead.
Package phpunit/php-token-stream is abandoned, you should avoid using it. No replacement was suggested.
```
これらは廃止されたパッケージだから変わりのパッケージを使うべきですという警告。
とりあえず無視。

エクスプローラで確認すると、laravelのプロジェクトが生成されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/1d63b941-29f8-534a-5a33-04ae5a2112e9.png)
まぁ、このやり方がいいのかわからないけど。

# 確認

php artisan serve で確認する。

```powershell
PS C:\Server\docker\laravel> docker compose up -d
[+] Running 3/3
 ✔ Container laravel-db-1          Started                                                                                                                                                                     0.5s
 ✔ Container laravel-php-1         Started                                                                                                                                                                     1.3s
 ✔ Container laravel-phpmyadmin-1  Started                                                                                                                                                                     1.1s
PS C:\Server\docker\laravel> docker compose exec php /bin/bash
root@77162592baa5:/var/www/html# ls
index.html  laravel7-project
root@77162592baa5:/var/www/html# cd laravel7-project/
root@77162592baa5:/var/www/html/laravel7-project# php artisan serve
Laravel development server started: http://127.0.0.1:8000
```

とりあえず起動。
そういえば8000ポートを外部からアクセスできるようにしていなかったので、compose.yamlを修正

```yaml:compose.yaml
services:
  db:
    image: mariadb:10.1
    environment:
      MARIADB_ROOT_PASSWORD: rootpass
      MARIADB_DATABASE: testdb
      MARIADB_USER: testuser
      MARIADB_PASSWORD: testpass
    volumes:
      - db-data:/var/lib/mysql
  phpmyadmin:
    image: phpmyadmin:5.2
    depends_on:
      - db
    environment:
      PMA_HOST: db
      PMA_USER: testuser
      PMA_PASSWORD: testpass
    ports:
      - "8080:80"
    volumes:
      - phpmyadmin-data:/sessions
  php:
    build: .
    depends_on:
      - db
    ports:
      - "8082:80"
      - "8000:8000"
    volumes:
      - ./src:/var/www/html
volumes:
  db-data:
  phpmyadmin-data:
```


外部から見られるように起動するには php artisan serve --host 0.0.0.0 で起動する必要があるようなので、それで起動

```powershell
root@7f66108fed22:/var/www/html/laravel7-project# exit
exit
PS C:\Server\docker\laravel> docker compose build
[+] Building 1.0s (12/12) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                                                           0.0s
 => => transferring dockerfile: 32B                                                                                                                                                                            0.0s
 => [internal] load .dockerignore                                                                                                                                                                              0.0s
 => => transferring context: 2B                                                                                                                                                                                0.0s
 => [internal] load metadata for docker.io/library/php:7.2-apache                                                                                                                                              0.9s
 => [1/8] FROM docker.io/library/php:7.2-apache@sha256:4dc0f0115acf8c2f0df69295ae822e49f5ad5fe849725847f15aa0e5802b55f8                                                                                        0.0s
 => CACHED [2/8] RUN apt-get update                                                                                                                                                                            0.0s
 => CACHED [3/8] RUN apt-get install -y libonig-dev                                                                                                                                                            0.0s
 => CACHED [4/8] RUN docker-php-ext-install pdo_mysql                                                                                                                                                          0.0s
 => CACHED [5/8] RUN apt-get install -y zlib1g-dev                                                                                                                                                             0.0s
 => CACHED [6/8] RUN docker-php-ext-install zip                                                                                                                                                                0.0s
 => CACHED [7/8] RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer                                                                           0.0s
 => CACHED [8/8] RUN cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini                                                                                                                      0.0s
 => exporting to image                                                                                                                                                                                         0.0s
 => => exporting layers                                                                                                                                                                                        0.0s
 => => writing image sha256:4b671e1e7644abdda5eb9af773f36a8aa2f8b2b8869e6fc2d3d54b3f960de7c5                                                                                                                   0.0s
 => => naming to docker.io/library/laravel-php                                                                                                                                                                 0.0s
PS C:\Server\docker\laravel> docker compose up -d
[+] Running 3/3
 ✔ Container laravel-db-1          Started                                                                                                                                                                     1.8s
 ✔ Container laravel-phpmyadmin-1  Running                                                                                                                                                                     0.0s
 ✔ Container laravel-php-1         Started                                                                                                                                                                     2.4s
PS C:\Server\docker\laravel> docker compose exec php /bin/bash
root@febe6c3dd1ea:/var/www/html# cd laravel7-project/
root@febe6c3dd1ea:/var/www/html/laravel7-project# php artisan serve --host 0.0.0.0
Laravel development server started: http://0.0.0.0:8000
[Mon May 15 10:12:23 2023] 172.20.0.1:39056 [200]: /favicon.ico
```

無事参照できた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/f9d9e737-e6ad-cc51-23c5-1040b8be7fc3.png)

これで、Laravelのお勉強ができる！

# おまけ
MariaDB 10.1の場合、MARIADB_DATABASEなどの環境変数はMYSQL_DATABASEのようにMYSQL_はじまりで定義しないといけないのね・・・

# 参考
- [Laravelの開発環境をdocker-composeで自作してみる](https://zenn.dev/naoyuki42/articles/ae215286ba92b2)
- [Laravelインストール時に出たzipのエラー解決備忘録](https://qiita.com/nejimawaso/items/55512b40b724e35880c3)
- [dockerfileでPHPのzip拡張を導入するメモ](https://qiita.com/Y-Kanoh/items/9d450a6868183557042f)
- [Laravel on Docker で php artisan serve するとlocalhost:8000が見れない](https://qiita.com/dyoshikawa/items/ec1c00df0f6276fdbae2)