Quantcast
Channel: ほりひログ
Viewing all articles
Browse latest Browse all 44

PHP8/Laravel8 アプリを App Service on Linux で動かす方法 (2022/04 暫定版)

$
0
0

どうやら App Service on Linuxで PHP8 / Laravel8 のアプリを動かす時に、いろいろ気を付けることがあるようなので、回避策含め備忘録としてまとめておく。

主な注意点

大きく分けて二つ。

  1. PHPを動かす Web サーバーの設定
  2. ビルド方法

1. Web サーバー設定

App Service on LinuxPHPのコンテナー イメージは、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

#!/bin/bash

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

追えるとこまで頑張ってみた感じ、これは、

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

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

なので、この PHPバイナリーは今の Kudu コンテナーでは実行できない、という話。
たぶん PHPバイナリーをビルドしている環境が stretchだったのではないか、という疑惑。

一応、修正済みの Oryx が GitHub上にはリリースされているので、Azure 上への次のリリース*2を待てばビルドできるようになるはず。

github.com


(以下 4/30 追記)

上記修正が適用されているかどうかは、Kudu コンソール上で oryx --versionを実行してみて、ReleaseTagName20220427.1かそれ以降になっているかを見たらいいっぽい。

(追記ここまで)


それが待てない人は以下の回避策をお試しあれ。

回避策 1. Oryx でビルドしない

最初はシンプルな策、Oryx でのビルドをやめる。
Oryx でビルドできないんだから、ローカルや CI 環境でビルドして、ビルド済みのものを App Service にデプロイしてしまえばいい。

App Service のアプリケーション設定で SCM_DO_BUILD_DURING_DEPLOYMENTfalseを指定すると、デプロイ時のビルドは無効になる。

回避策 2. Kudu を stretchベースにする

issue で Corp. のエンジニアから出ている方法で、アプリケーション設定で SCM_DISABLE_BUSTER_KUDUtrueを指定する。
すると、Kudu のコンテナーが stretchベースのものになるらしい。

試してみる。

既定の状態は busterなのは上のスクショの通り。

次に SCM_DISABLE_BUSTER_KUDUtrueを指定した状態。

おー確かに 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_PATHPRE_BUILD_COMMANDを使う。
単発コマンドでいい場合、またはワンライナーで書ける場合は PRE_BUILD_COMMANDがいいが、スクリプトファイルを書く場合は PRE_BUILD_SCRIPT_PATHでファイルを指定する。

例えば、下記のようなスクリプトscripts/prebuild.shとして配置するなら、PRE_BUILD_SCRIPT_PATHscripts/prebuild.shと指定する。

scripts/prebuild.sh

#!/bin/bashPHP_VERSION=8.0.17cd /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 次リリースを待つ - 公式方法。「いつから使える」ってはっきりしたことは言えない

あなたはどれを選びます?

*1:KuduLite と言われるコンテナー イメージ。1. の nginx が動くアプリ コンテナーとは別コンテナー

*2:2022 年 5 月か 6 月かな?

*3:App Service にはこういう知らない設定がいっぱいある

*4:なんで公開しているんですかねぇ。。。


Viewing all articles
Browse latest Browse all 44

Trending Articles