どうやら App Service on Linux で PHP8 / Laravel8 のアプリを動かす時に、いろいろ気を付けることがあるようなので、回避策含め備忘録としてまとめておく。
主な注意点
大きく分けて二つ。
- PHP を動かす Web サーバーの設定
- ビルド方法
1. Web サーバー設定
App Service on Linux の PHP のコンテナー イメージは、PHP7 までは apache だったのが nginx に変更になった。
それに伴って、PHP を動かす設定も変えないといけないらしい。
# ちなみに、OS は Debian 10 (buster
)
具体的には、Startup Command
として、nginx へのリクエストを PHP アプリへルーティングする?ための設定を変更する処理を指定する。
まずは nginx の設定変更。
App Service on Linux 内の nginx は /etc/nginx/sites-available/default
を見ているので、これをコピーして PHP8/Laravel8 の構成に合わせて変更する。
これをアプリケーション プロジェクトの scripts/default
として保存しておく。
scripts/default
server {
#proxy_cache cache;
#proxy_cache_valid 200 1s;
listen 8080;
listen [::]:8080;
# 変更 1) index.php があるディレクトリを指定。これは Laravel8 の場合。
root /home/site/wwwroot/public;
index index.php index.html index.htm;
server_name example.com www.example.com;
location / {
index index.php index.html index.htm hostingstart.html;
# 変更 2) 詳細は https://docs.microsoft.com/en-us/answers/questions/542749/deploying-an-app-service-with-laravel-8-and-php-8.html
try_files $uri $uri/ /index.php?$args;
}
# 以下デフォルトのまま
}
次に scripts/default
を /etc/nginx/sites-available/default
に戻して、nginx を再起動し、変更した設定を反映するスクリプトを書く。
同じく scripts/startup.sh
としておく。
scripts/startup.sh
cp /home/site/wwwroot/scripts/default /etc/nginx/sites-available/default
service nginx reload
最後に App Service 側の Startup Command
を使って、起動時に scripts/starup.sh
を実行するよう設定する。

これで nginx と PHP との間の設定は解決。
2. ビルド設定
2022 年 4 月現在、PHP8 のアプリは既定の設定のままだと App Service のビルド エンジンである Oryx でのビルド (compser install
コマンドの実行) ができない。
下記 Oryx の GitHub リポジトリの issue にある通り、Kudu コンテナー*1上でのビルド時に必要なファイル libonig.so.4
が見つからずエラーになってしまう。
github.com

追えるとこまで頑張ってみた感じ、これは、
- Kudu コンテナー上での
composer install
実行に使用される PHP バイナリーが libong.so.4
とリンクしている
- リンクされている
libonig.so.4
は、Debian 9 (コードネーム stretch
) 向けのライブラリーである
https://packages.debian.org/search?keywords=libonig
- でも Kudu コンテナーは Debian 10 (コードネーム
buster
) ベースのコンテナーである

だから libonig.so.4
は入っていないし入れられない。

なので、この PHP バイナリーは今の Kudu コンテナーでは実行できない、という話。
たぶん PHP バイナリーをビルドしている環境が stretch
だったのではないか、という疑惑。
一応、修正済みの Oryx が GitHub 上にはリリースされているので、Azure 上への次のリリース*2を待てばビルドできるようになるはず。
github.com
(以下 4/30 追記)
上記修正が適用されているかどうかは、Kudu コンソール上で oryx --version
を実行してみて、ReleaseTagName
が 20220427.1
かそれ以降になっているかを見たらいいっぽい。

(追記ここまで)
それが待てない人は以下の回避策をお試しあれ。
回避策 1. Oryx でビルドしない
最初はシンプルな策、Oryx でのビルドをやめる。
Oryx でビルドできないんだから、ローカルや CI 環境でビルドして、ビルド済みのものを App Service にデプロイしてしまえばいい。
App Service のアプリケーション設定で SCM_DO_BUILD_DURING_DEPLOYMENT
に false
を指定すると、デプロイ時のビルドは無効になる。
回避策 2. Kudu を stretch
ベースにする
issue で Corp. のエンジニアから出ている方法で、アプリケーション設定で SCM_DISABLE_BUSTER_KUDU
で true
を指定する。
すると、Kudu のコンテナーが stretch
ベースのものになるらしい。
試してみる。
既定の状態は buster
なのは上のスクショの通り。
次に SCM_DISABLE_BUSTER_KUDU
に true
を指定した状態。

おー確かに stretch
になった。マジかよ知らなかった*3。
これで libonig.so.4
が使えるので、composer install
はできるはず。

ただし、ビルドは stretch
ベースのコンテナー上で行われる一方で、実際のアプリケーションは buster
ベースのランタイム コンテナー上で動くことになるので、ライブラリーによってはこの違いで動かなくなる(かもしれない)。
回避策 3. PHP バイナリー自体を置き換える
Kudu コンテナー内での composer install
に使われている PHP バイナリーは、上記の通り stretch
上でビルドされたものと推察されるが、これは Oryx を起動した時にここからダウンロードして Kudu コンテナー内に展開したもの。
これを buster
上でビルドされた PHP バイナリーとに置き換えてしまえばいい。
そうすると
buster
ベースの KutuLite コンテナー
buster
向けの PHP バイナリーを使って composer install
を実行してビルド
- ランタイムも
buster
という感じで全て buster
で統一できてハッピー。
buster
向け PHP バイナリーは自前でビルドしてデプロイ パッケージに入れることもできるし、実は stretch
向けの PHP バイナリーと同じところにあるのでそっちも使える。
「置き換え」処理そのものは、Oryx が持っている「ビルド前後に任意のスクリプトを実行する」仕組みを使う。
github.com
PHP バイナリーの置き換えはビルドの前にやらないといけないので、 PRE_BUILD_SCRIPT_PATH
か PRE_BUILD_COMMAND
を使う。
単発コマンドでいい場合、またはワンライナーで書ける場合は PRE_BUILD_COMMAND
がいいが、スクリプト ファイルを書く場合は PRE_BUILD_SCRIPT_PATH
でファイルを指定する。
例えば、下記のようなスクリプトを scripts/prebuild.sh
として配置するなら、PRE_BUILD_SCRIPT_PATH
に scripts/prebuild.sh
と指定する。
scripts/prebuild.sh
PHP_VERSION=8.0.17
cd /tmp
mkdir -p /tmp/oryx/platforms/php/${PHP_VERSION}
curl -O https://oryx-cdn.microsoft.io/php/php-buster-${PHP_VERSION}.tar.gz
tar -xzf /tmp/php-buster-${PHP_VERSION}.tar.gz -C /tmp/oryx/platforms/php/${PHP_VERSION}
これで、composer install
の直前に buster
向けの PHP バイナリーに差し替えができる。
懸念点は Corp. のエンジニアから「そっちのバイナリーは、依存モジュールが変わっているから、何が起こるか。。。」(超意訳)と言われたこと*4だけど、試した限り composer install
くらいなら動く。
もちろん自前でビルドして持ち込む場合は自己責任で。
startup.sh
など scripts
配下もまとめて GitHub に公開してみた。
github.com
一応、修正リリースと同じアプローチのはず。
ビルド エラー回避策のまとめ
ここまで書いたビルド設定に関する 4 種類の回避策のまとめ。
# |
回避策 |
設定方法 |
メリット |
デメリット |
1 |
Oryx でのビルドをやめる |
SCM_DO_BUILD_DURING_DEPLOYMENT = false |
ビルド環境の自由度が高い |
CI 等のビルド環境が別途必要 |
2 |
stretch ベースの Kudu コンテナー |
SCM_DISABLE_BUSTER_KUDU = true |
設定簡単 |
ビルド/ランタイム環境でベース OS が異なり、アプリ実行時に不整合が起こるかも。 |
3 |
ビルド用 PHP バイナリーの変更 |
PRE_BUILD_SCRIPT_PATH = <script_path> |
ビルド/ランタイム環境の統一感 |
動くことは動くがエンジニアが前向きじゃない。自己責任。 |
4 |
次リリースを待つ |
- |
公式方法。 |
「いつから使える」ってはっきりしたことは言えない |
あなたはどれを選びます?