Laravel Horizonインストール時のエラー require ext-pcntl *....への対処法

Laravel8 + PHP 7.4.7のdocker環境でHorizonをインストールしようとしたら、以下のようなエラーが出ました。


```shell
$ composer require laravel/horizon
Using version ^5.7 for laravel/horizon
./composer.json has been updated
Running composer update laravel/horizon
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - laravel/horizon[v5.7.0, ..., 5.x-dev] require ext-pcntl * -> it is missing from your system. Install or enable PHP's pcntl extension.
    - Root composer.json requires laravel/horizon ^5.7 -> satisfiable by laravel/horizon[v5.7.0, 5.x-dev].
```

PHPの拡張pcntl(Process Controll)がないらしいです。


### 解決策 Dockerfileに拡張機能インストール処理を追記
私の場合、dockerで環境構築していたので、
webサーバー(PHPの処理を書くコンテナ)のDockerfileにpcntlをインストールしました。

Before

```
FROM php:7.4-apache

# pcntl is requirement of horizon
RUN apt-get update \
    && apt-get install -y zip unzip vim libpq-dev \
    && docker-php-ext-install pdo_mysql pdo_pgsql
```

After
docker-php-ext-installコマンドの後ろに`pcntl`を追加

docker-php-ext-installコマンドがない人は、PHPコンテナ内をfindで探し、あるなら下記のように追記、なければ別のPHP拡張インストーラーが入っているはずなので、そのインストーラーの処理に追記しましょう。

```
FROM php:7.4-apache

# pcntl is requirement of horizon
RUN apt-get update \
    && apt-get install -y zip unzip vim libpq-dev \
    && docker-php-ext-install pdo_mysql pdo_pgsql pcntl
```

後はコンテナを立て直して`composer require laravel/horizon`すればOK!

```shell
$ composer require laravel/horizon

Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing laravel/horizon (v5.7.0): Downloading (100%)         
laravel/horizon suggests installing ext-redis (Required to use the Redis PHP driver.)
Package fzaninotto/faker is abandoned, you should avoid using it. No replacement was suggested.
Writing lock file
Generating optimized autoload files
composer/package-versions-deprecated: Generating version class...
composer/package-versions-deprecated: ...done generating version class
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: facade/ignition
Discovered Package: laravel/ui
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
```

#### 代替案 CLIで今すぐインストール

代わりというのもアレですが、既にコンテナが立っている状態であれば、Dockerfileを編集せずにインストールすることも可能です。

```
// コンテナ内で実行
docker-php-ext-install pcntl


// もしパスが通ってなかったら、コンテナ内でphpなどのパスにないか確認・移動(大抵同じ箇所にある)
which php
# -> /usr/local/bin/php

cd /usr/local/bin
docker-php-ext-install pcntl
```
以上で完了です!

#### こんな対応もあるらしい

私自身は「解決策」の方法を取り、導入・動作まで確認できましたが、調べる過程では別の方法も提案されていました。

①[Laracasts laravel horizon install error]
(https://laracasts.com/discuss/channels/laravel/laravel-horizon-install-error)
`composer require laravel/horizon --ignore-platform-reqs`コマンドでインストールする。
オプション(`--ignore-platform-reqs`)で環境(PHP側の拡張がないこと)を無視してインストールできるらしい。
=> [packagistでHorizonのrequires](https://packagist.org/packages/laravel/horizon#v5.6.6)を見る限り、pcntlがないとヤバそうなので、不採用。

②[Laracasts Install pcntl ext](https://laracasts.com/discuss/channels/laravel/install-pcntl-ext)
PHPをダウンロードして、コマンドを打って設定できるみたい。
既にdockerで環境を作った場合、ここに示されているようなファイルが見つからなかったので見送り。
MAMP環境での導入方法が書かれているので、同じ環境の人は試してもいいかも



###  資料

①[Docker上でPHP拡張モジュール『GD』を有効化する](https://qiita.com/Soh1121/items/17dcdc815a1d22f31788)
https://laracasts.com/discuss/channels/laravel/install-pcntl-ext
https://github.com/mlocati/docker-php-extension-installer


#### まとめ
今回の対応は、資料①の記事を多いに参考にさせてもらいました(入れる拡張が違うだけで、やってることは変わらない)。
普段は追加機能の開発でcomposerを使ってライブラリを入れるくらいで、
PHPの拡張を入れる必要に迫られることは少なかった(ぶっちゃけ海外でもこういう人が多いっぽい)ので勉強になりました。