Docker内のPHP7.4からMS SQLServerに接続する

## はじめに
DockerでのLaravel開発において、`SQLServer`との接続を試みたところ、色々と壁にぶち当たったので、
その記録を残しておく。

## 前提
以下の環境構築は完了しているものとする。
- PHP7.4コンテナ作成&起動済み
- SQLServerコンテナ作成&起動済み
- .envフォイルや/config/database.phpファイルはSQLServer接続用に編集済み

## 今回のゴール
PHPコンテナ内で、`php artisan migrate`が実行でき、
デフォルトで入っているUsersテーブル用のマイグレーションファイルからusersテーブルが作成されること。
また、作成したテーブルをホスト側のSSMS(SQL Server Management Studio)で確認できること。

## 早速マイグレーションしてみる

PHPコンテナ内に入り、マイグレーションを実行してみる。
するとエラーが発生した。
```
$ php artisan migrate

Illuminate\Database\QueryException : could not find driver (SQL: select * from 
information_schema.tables where table_schema = laravel and
...省略...
```
ドライバが見つからないと言われている。
要は、SQL Serverに接続するためのPHP用ドライバが見つかりませんよ～とのこと。
では、ドライバをインストールしていきましょう。

## ドライバのインストール
手順としては、まずODBCドライバをインストールし、peclでPHP用ドライバをインストールする。
ODBCドライバがない場合、peclでのインストール時にビルドに失敗するため。
直接コンテナ内でインストールするのではなく、再利用できるようにPHPの`Dockerfile`を編集してビルドし直す事にする。

まずは、Microsoftの公式ドキュメントにある[ODBCドライバのインストール](https://docs.microsoft.com/ja-jp/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-ver16)と[PHPドライバのインストール](https://docs.microsoft.com/ja-jp/sql/connect/php/installation-tutorial-linux-mac?view=sql-server-ver16)
に従ってコマンドを追加する。

```Dockerfile:Dockerfile
FROM php:7.4-fpm

# ...省略...

# ODBCドライバのインストール
ENV ACCEPT_EULA=Y
RUN apt-get update && apt-get install -y apt-transport-https gnupg2
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - 
RUN curl https://packages.microsoft.com/config/debian/10/prod.list > /etc/apt/sources.list.d/mssql-release.list 
RUN apt-get update 
RUN ACCEPT_EULA=Y apt install -y msodbcsql17 mssql-tools
RUN apt-get install -y unixodbc-dev7777
# PHPドライバのインストール
RUN pecl install sqlsrv
RUN pecl install pdo_sqlsrv
RUN docker-php-ext-enable sqlsrv pdo_sqlsrv
```
追加して保存が出来たら、`docker-comopse.yml`ファイルがあるディレクトリに移動し、
コマンド`docker-compose up -d --build`を実行し、イメージを再構築してコンテナを作成&起動する。
<details><summary>--buildオプションについて</summary>
ここで、--buildオプションを書かないと、編集したDockerfileは反映されない。
docker-compose up を実行すると、キャッシュに保存されているビルド済みのイメージが使用される。
そのため、再ビルドするためにはこのオプション--buildをつけておく必要がある。
</details>

では、実行してみる。
```
$ docker-compose up -d --build
```

### エラーが発生した。
ビルドが失敗し、下記のようなエラーが出た。
```
=> ERROR [ 9/19] RUN ACCEPT_EULA=Y apt install -y msodbcsql17 mssql-tools

... 省略 ...

#13 4.724 The following packages have unmet dependencies:
#13 4.770  libodbc1 : PreDepends: multiarch-support but it is not installable
#13 4.771  odbcinst1debian2 : PreDepends: multiarch-support but it is not installable
#13 4.782 E: Unable to correct problems, you have held broken packages.
```
ODBCドライバをインストールする箇所で失敗している。

### 解決策
このエラーと丸一日格闘していたわけだが、何とか解決策を発見した。
それがこちら。`Dockerfile`の先頭を修正する。
```Dockerfile:Dockerfile
FROM php:7.4-fpm-buster 　
#-busterを追加した。
```

Debianのバージョン10に対応するコードネームである`-buster`を追加した。

最後に、もう一度`docker-compose up -d --build`をたたき、無事ビルドが成功しコンテナが起動した。
コンテナの中に入り、`php artisan migrate`にてマイグレーションが成功し、
ホスト側のSSMSでもusersテーブルが作成されたのを確認できた。

時間がかかったが、エラー周りの事やドライバ関連の事を
ネットから色々と知見が得れたので、一石二鳥としよう。

今回、エラーメッセージの内容に細かくは触れていないが、
気が向いたらそちらについても投稿しようと思う。

## 参考資料

- https://github.com/microsoft/msphpsql/issues/1346
- https://github.com/Namoshek/docker-php-mssql/blob/master/7.4/fpm/Dockerfile
- https://docs.microsoft.com/ja-jp/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-ver16
- https://docs.microsoft.com/ja-jp/sql/connect/php/installation-tutorial-linux-mac?view=sql-server-ver16