🐘

FrankenPHPでスタンドアロンなコマンドを作ってみた

2023/12/20に公開1

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とは

https://frankenphp.dev/

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 --platform=linux/amd64 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