既存のLaravel5.xプロジェクトをDocker環境に移行する

新規でプロジェクトを立ち上げるなら[Laravel Sail](https://readouble.com/laravel/9.x/ja/sail.html)を使えば楽々Docker環境を構築できますが、
既存のHomesteadで動かしている~~古臭い~~プロジェクトをDockerに移行出来ないかなというのが本記事の趣旨です。

Laravel Sailとやっていることは似ていて、
+ ローカル環境でcomposer installなどをして環境構築
+ docker-composeなどでコンテナ作成
という流れになっています。

# HomesteadからDockerに移す利点
+ 簡単に環境を用意できる
+ 毎日の起動が圧倒的に早い
+ VMを起動するより軽量

# 構築環境
+ Windows11
+ Ubuntu 22.04 LTS(Microsoft Storeで置いているやつ）
+ Laravel 5.5.50のプロジェクト

# php7.xの用意とcomposer install
特に何も考えないでWindowsやUbuntuにphpをインストールすると、バージョンが8.xになっていると思います。（バージョンは``php -v``で確認できます）
Laravel5.xのような古いバージョンはphp7.xでないと動作しません。
Windowsの環境変数のPathを変える方法もありますが、バージョンの切り替えが面倒なので、Ubuntu内にupdate-alternativesを入れて切り替える方法を取りたいと思います。
こうするとPowerShellは最新版、Ubuntuは任意のバージョンのphp環境となり、ターミナルのタブ切り替えだけでphpのバージョン違いに対応できるためおススメです。
## 7.xのphpを用意する（[参照](https://qiita.com/murakami77/items/a9945f2a8e51ca3791de)）
参照先ままで、Ubuntuで以下の操作を行います。
```
sudo add-apt-repository ppa:ondrej/php 
```
でリポジトリを追加した後、
```
sudo apt install -y php7.3
sudo apt install -y php7.4
sudo apt install -y php8.0
```
など好きなphpバージョンをインストールします。
```
sudo update-alternatives --install /usr/bin/php php /usr/bin/php7.3 100 //最後の数字は
sudo update-alternatives --install /usr/bin/php php /usr/bin/php7.4 110 //優先度で、
sudo update-alternatives --install /usr/bin/php php /usr/bin/php8.0 120 //高い程優先される
```
``sudo update-alternatives --config php``でバージョン切り替えが出来るようになります。

## composer install
次にLaravelプロジェクトのgit clone先にあるcomposer.json内を編集します。
```composer.json
    "config": {
        "platform": {
            "php": "7.3"        
        }
    }
```
composerがphp7.3に対応したパッケージを取ってくるようにします。7.3の部分に任意で変更できます。
後は``composer install``を行えばOKです。

### 遭遇したエラー一覧
``Script @php artisan package:discover –ansi handling the post-autoload-dump event returned with error code 1``
phpのバージョンが違うとこのエラーが出てきます。他にもAPP_ENVの指定忘れでも起きるそうです。

``class ○○Provider not found``
色々な原因がありますが、自分の場合はProviderディレクトリ内のhogehogeディレクトリが'h'ogehogeとなっていたのが原因でした。Laravelのapp内のファイル/ディレクトリ名は全部大文字から始めないとphp artisan時には見つけてくれないようです。Hogehogeと変更したら解決しました。命名規則はとても大切

# Dockerの設定
Laravelプロジェクト内にdocker-compose.yamlとDockerfileという名前のファイルを作ります。
docker-compose.yamlはLaravel Sailのものを流用します。service、volumes,networks名やportsは自由に変更できますが、整合性に気を付けてください。
```docker-compose.yaml
version: '3'
services: 
    laravel:
        image: 'bitnami/laravel'
        build: 
            context: .
            dockerfile: Dockerfile
        command: 'php artisan serve --host=0.0.0.0'
        volumes:
            - '.:/var/www/html'
        networks:
            - sail
        depends_on:
            - mysql
        ports:
            - 8000:8000
    mysql:
        image: 'mysql/mysql-server:8.0'
        ports:
            - '3306:3306'
       #.env内が参照されます
        environment:
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ROOT_HOST: '%'
            MYSQL_DATABASE: '${DB_DATABASE}'
            MYSQL_USER: '${DB_USERNAME}'
            MYSQL_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ALLOW_EMPTY_PASSWORD: 1
        volumes:
            - 'sail-mysql:/var/lib/mysql'
        networks:
            - sail
        healthcheck:
            test:
                - CMD
                - mysqladmin
                - ping
            retries: 3
            timeout: 5s
networks:
    sail:
        driver: bridge
volumes:
    sail-mysql:
        driver: local
```

Dockerfileは、[こちら](https://medium.com/geekculture/the-easiest-way-to-dockerize-your-laravel-application-94977fe2ed6d)の記事のコピペでほぼ問題ありません。最後のcomposer installは不要なので消しています。
```Dockerfile
# 任意のバージョンを入力
FROM php:7.3-fpm-alpine

RUN docker-php-ext-install pdo pdo_mysql sockets
RUN curl -sS https://getcomposer.org/installer​ | php -- \
    --install-dir=/usr/local/bin --filename=composer

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# docker-compose.yaml内のLaravelサービスのvolumesと一致させる
WORKDIR /var/www/html
COPY . .
```

後は``docker-compose up -d``で立ち上がると思います。Build作業はPCスペックによりますが、contextを``.``としているため時間がかかります。

# まとめ
Dockerfileやdocker-compose.yamlを~~コピペして~~作るのは初めてだったので、普段使ってる``sail up -d``の裏側や原理を学習する良い機会となりました。
dbや他イメージ（wordpressなど）を組み合わせることでHomesteadよりも素早く、共有可能な環境構築が出来るのは、学習コストに不釣り合いなくらいな大きな利点なので、今後も継続して学習しモノにしたいと思います。