FrankenPHPでスタンドアロンなコマンドを作ってみた
PHPアドベントカレンダー2023 day20の記事です。
les-tilleuls.coop の設立者の dunglasさん が開発しているFrankenPHPが先日v1.0.0になったので、試してみました。(なお、既にv1.0.1にアップデートされています)
dunglasさんはSymfony Core Teamのメンバーであり、api-platformの作者でもあります。
※ 2023年12月20日朝9時現在、codezineのこちらの記事 ではFrankenPHPはLaravelが作ったなどと書かれていますが、大間違いなので適切に訂正されることを望みます。なお、同記事はSymfonyのこともSymphonyと書いており大変遺憾です(Symfonyのスペルについては転載元のLaravel Newsも間違っている)。
FrankenPHPとは
PHPを動かすサーバーにもなり、PHPをスタンドアロンで動かすこともできるツールです。
FrankenPHPの上で動かすと、SymfonyやLaravelがちょっぱやになるとのこと。
FrankenPHPのインストール
アプリケーションサーバーとしてのFrankenPHPを使って自分のwebアプリケーションを動かしてみたい場合はdockerを使って試すことができるので特にインストールは必要ありません。
ローカルに直接インストールしたい場合は https://github.com/dunglas/frankenphp/releases からOSにあったバイナリをダウンロードすればOKです。
FrankenPHPでスタンドアロンコマンドラインアプリを作る
マニュアル に従ってスタンドアロンアプリを作ってみます。完了すると、作ったコマンドはPHPのない環境に持って行っても動くはずです。
コマンドラインアプリを用意
index.phpに名前を渡して挨拶するだけのど〜〜でもいいコマンドラインphpアプリを用意しました。
ソースコードは こちら
普通にPHPで動かすとこんな感じです。
% php index.php linkage
Hello linkage!
このコマンドラインアプリをスタンドアロン化してみようと思います。
static-build.Dockerfileを作る
https://frankenphp.dev/docs/embed/#creating-a-linux-binary にあるDockerfileをコピーしてファイルを作ります。
今回のど〜〜でもいいアプリには不要なpdo_sqlite extensionは消しました。
FROM dunglas/frankenphp:static-builder
# Copy your app
WORKDIR /go/src/app/dist/app
COPY . .
# Build the static binary, be sure to select only the PHP extensions you want
WORKDIR /go/src/app/
RUN EMBED=dist/app/ \
PHP_EXTENSIONS=ctype,iconv \
./build-static.sh
アプリケーションとしての動作に不要なファイルを消す
本当は /.git
や /.idea
, /tests
などprodに不要なファイルは消しなさいと書いてありますが、今回はど〜〜でもいいアプリを試したいだけなのでスキップします。
ビルドする
% docker build -t static-app -f static-build.Dockerfile .
[+] Building 302.4s (10/10) FINISHED
# (長いので後略)
M2 MacBookAir + Docker Desktopで特に問題なく完了しました。(時間は302secかかっています)
バイナリを取り出す
% docker cp $(docker create --name static-app-tmp static-app):/go/src/app/dist/frankenphp-linux-x86_64 my-app ; docker rm static-app-tmp
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
static-app-tmp
M2 MacBookAir上で実行しているのでエラーは出ましたが、my-appを得ることができました。
.git等を消してない影響か、ファイルサイズは大きめです。
% ls -al
total 244280
drwxr-xr-x 12 mama staff 384 12 20 09:21 .
drwxr-xr-x 29 mama staff 928 12 20 08:21 ..
drwxr-xr-x 12 mama staff 384 12 20 09:01 .git
-rw-r--r--@ 1 mama staff 31 12 20 08:23 .gitignore
drwxr-xr-x 8 mama staff 256 12 20 09:13 .idea
-rw-r--r--@ 1 mama staff 437 12 20 08:24 composer.json
-rw-r--r--@ 1 mama staff 81573 12 20 08:22 composer.lock
-rw-r--r-- 1 mama staff 240 12 20 08:30 index.php
-rwxr-xr-x 1 mama staff 124972656 12 20 09:20 my-app
drwxr-xr-x@ 3 mama staff 96 12 20 08:27 src
-rw-r--r-- 1 mama staff 296 12 20 09:00 static-build.Dockerfile
drwxr-xr-x@ 13 mama staff 416 12 20 08:22 vendor
動作を試す
linux用にビルドしてしまったのでローカルのMac上では動かない&cliのPHPが入ってしまっているので、ubuntuのプレーンなDockerコンテナ上で動かしてみることにしました。
% docker run -it --rm -v /Users/mama/projects/myhello:/root ubuntu
root@f3c79155fb7e:/# php -v
bash: php: command not found
root@f3c79155fb7e:~# ./my-app php-cli index.php linkage
Hello linkage!
php-cli index.phpという尻尾は見えてますが、PHPの入ってない環境でもPHPが動くコマンドが作れました!
まとめ
phperの永遠の憧れ(?)、スタンドアロンコマンドラインアプリがとても簡単に作れることがわかりました。
夢が広がりますね!
Discussion
CLIだけだと
これも選択肢にあがるかなとおもいました!