FrankenPHP をソースコードからビルドする完全ガイド — 動的 libphp 方式でカスタムバイナリを作る
FrankenPHP をソースコードからビルドする完全ガイド — 動的 libphp 方式でカスタムバイナリを作る【免费下载链接】frankenphp The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp本ガイドは、PHP を動的ライブラリlibphpとしてロードする FrankenPHP バイナリの作成手順を解説します。公式ドキュメント docs/ja/compile.md を骨格に、リポジトリ内のビルドスクリプトgo.sh、build-static.shや Docker ビルド定義Dockerfile、docker-bake.hclの実装を照合しながら、Homebrew による PHP の導入、PHP 本体のソースコンパイル、xcaddy を使った最終バイナリの組み立てまでを順を追って説明します。読み終えると、任意の Caddy モジュールと FrankenPHP 拡張を組み込んだ独自バイナリを、自分の開発環境向けに再現できるようになります。ビルド方式の全体像FrankenPHP のバイナリを作る方法は大きく 2 つに分かれます。PHP を動的ライブラリとしてロードする方式推奨システムにインストールした PHPZTS ビルドのlibphpを、Go で書かれた FrankenPHP 本体から cgo 経由でリンク・ロードします。本ドキュメントの主題です。完全静的・ほぼ静的なビルドstatic-php-cli を利用し、PHP インタープリター・Caddy・FrankenPHP を 1 つのポータブルなバイナリにまとめる方式。詳細は docs/ja/static.md を参照してください。前者が推奨される理由は、システムの PHP バージョンや拡張をそのまま活かせること、ビルドが比較的シンプルであることです。互換性の要件として、FrankenPHP は PHP 8.2 以上に対応していますdocs/ja/compile.md。実際、docker-bake.hcl のPHP_VERSION変数のデフォルト値は8.2,8.3,8.4,8.5となっており、このバージョン帯がビルドマトリクスとして維持されていることが確認できます。PHP のインストールHomebrew を使う場合Linux と MacFrankenPHP と互換性のあるlibphpを最も簡単に入手する方法は、Homebrew PHP が提供するZTS パッケージを使うことです。FrankenPHP は PHP をスレッド内で実行するため、Zend Thread SafetyZTSが有効な PHP が必要です。まず Homebrew をインストールしていない場合は導入し、続けて PHP の ZTS バリアント、Brotliオプション、圧縮サポート用、watcherオプション、ファイル変更検出用をインストールしますbrew install shivammathur/php/php-zts brotli watcher brew link --overwrite --force shivammathur/php/php-ztsbrew link --overwrite --forceによって、シェルからphp-configコマンドが確実に参照できるようになります。php-configは後述のCGO_CFLAGS/CGO_LDFLAGSの解決に必須のコマンドです。PHP をソースからコンパイルする場合もう 1 つの方法は、FrankenPHP が必要とするオプションを明示して PHP をソースからビルドすることです。まず PHP のソース を取得して展開しますtar xf php-* cd php-*/次に、プラットフォームに応じてconfigureスクリプトを実行します。以下のフラグは必須ですが、拡張モジュールや追加機能のために他のフラグを併記することも可能です。Linux./configure \ --enable-embed \ --enable-zts \ --disable-zend-signals \ --enable-zend-max-execution-timers各フラグの意味は次のとおりですフラグ役割--enable-embedPHP を組み込み用途の共有ライブラリlibphpとしてビルドするために必須--enable-ztsスレッドセーフな PHP を有効化。FrankenPHP はリクエストを複数スレッドで処理するため必須--disable-zend-signalsPHP 側のシグナル処理を無効化。Go ランタイムがシグナルを管理する構成との整合のため--enable-zend-max-execution-timersリクエストの実行時間上限タイマーを Zend エンジンに持たせるために推奨・必須MacHomebrew パッケージマネージャーで必須およびオプションの依存関係をインストールしますbrew install libiconv bison brotli re2c pkg-config watcher echo export PATH/opt/homebrew/opt/bison/bin:$PATH ~/.zshrcbisonとre2cは PHP のパーサー生成に、pkg-configは依存ライブラリの解決に使われるビルドツールチェーンです。Apple 標準のbisonはバージョンが古いことがあるため、Homebrew 版のbisonをPATHの先頭に置く必要があります。libiconvは文字コード変換のため、明示的にパスを渡します。その後、以下のように configure スクリプトを実行します./configure \ --enable-embed \ --enable-zts \ --disable-zend-signals \ --with-iconv/opt/homebrew/opt/libiconv/Linux でも同様に、ディストリビューションのパッケージマネージャーでbison・re2c・pkg-configに相当するビルドツールチェーンを揃えておくと、PHP 本体のソースコンパイルがスムーズに進みます。PHP のコンパイル最後に、コア数の分だけ並列ビルドしてシステムへインストールしますmake -j$(getconf _NPROCESSORS_ONLN) sudo make install$(getconf _NPROCESSORS_ONLN)は利用可能な CPU コア数を返すため、-jで最大限の並列度が得られます。インストール後、php-config --includes/--ldflags/--libsが正しい値を返せば、次のステップに進めます。オプション依存関係のインストールFrankenPHP の一部機能は、システムにインストールされているオプションの依存パッケージに依存します。依存関係を用意しない場合、またはビルド時に明示的に無効化したい場合は、Go コンパイラにビルドタグを渡します機能依存関係無効化するためのビルドタグBrotli 圧縮Brotlinobrotliファイル変更時のワーカー再起動Watcher CnowatcherBrotliHTTP レスポンスの圧縮コーデックの 1 つ。有効時は Caddy のencodeディレクティブでbrを利用できます。Watcher Cファイル変更を検知してワーカーモードの PHP プロセスを自動再起動する機能開発時のホットリロードを担います。リポジトリでは internal/watcher/ と watcher.go にその実装があり、caddy/go.mod にもgithub.com/e-dant/watcherが依存として宣言されています。なお、リポジトリ内の Dockerfile では watcher をcmakeでビルドして/usr/local/libにインストールし、生成バイナリにlibwatcherを同梱する構成になっています。機能を無効化したくない場合は、両ライブラリを導入した上でタグを付けずにビルドしてください。Go アプリのコンパイルPHP の準備が整ったら、いよいよ最終バイナリをビルドします。xcaddy を使う場合推奨推奨される方法は、xcaddy を使って FrankenPHP をコンパイルすることです。xcaddyを使うと、Caddy のカスタムモジュールや FrankenPHP 拡張を--withで簡単に追加できますCGO_ENABLED1 \ XCADDY_GO_BUILD_FLAGS-ldflags-w -s -tagsnobadger,nomysql,nopgx \ CGO_CFLAGS$(php-config --includes) \ CGO_LDFLAGS$(php-config --ldflags) $(php-config --libs) \ xcaddy build \ --output frankenphp \ --with github.com/dunglas/frankenphp/caddy \ --with github.com/dunglas/mercure/caddy \ --with github.com/dunglas/vulcain/caddy # 追加のCaddyモジュールとFrankenPHP拡張をここに追加各環境変数の役割を整理します環境変数意味CGO_ENABLED1cgo を有効化。libphpをリンクするために必須XCADDY_GO_BUILD_FLAGSGo ビルドに渡す追加フラグ。-ldflags-w -sでデバッグ情報を削ってバイナリを縮小し、-tagsnobadger,nomysql,nopgxで Caddy の不要なストレージモジュールBadger・MySQL・pgxを無効化CGO_CFLAGSPHP のヘッダー探索パス。php-config --includesの出力を利用CGO_LDFLAGSリンク時のライブラリ指定。php-config --ldflagsとphp-config --libsの出力を利用--withで指定しているのは以下のモジュール群ですgithub.com/dunglas/frankenphp/caddyFrankenPHP 本体の Caddy モジュールcaddy/frankenphp/main.go でも標準・frankenphp・mercure・vulcain が blank import されていますgithub.com/dunglas/mercure/caddyリアルタイム通信プロトコル Mercure の統合github.com/dunglas/vulcain/caddyHTTP/2 Server Push を代替する Vulcain の統合caddy/go.mod を見ると、Caddy v2.11.4・frankenphp v1.12.7 をはじめ、mercure・vulcain・caddy-cbrotli・e-dant/watcher などが依存として宣言されており、--withで追加するモジュール群と整合しています。独自の Caddy モジュールや FrankenPHP 拡張を追加する場合は、この行の後ろに--with モジュールパスを追記するだけです。musl libcAlpine Linuxで Symfony を使う場合の注意[!TIP] musl libcAlpine Linux のデフォルトと Symfony を使用している場合、デフォルトのスタックサイズを増やす必要がある場合があります。そうしないと、PHP Fatal error: Maximum call stack size of 83360 bytes reached during compilation. Try splitting expressionのようなエラーが発生する可能性があります。これを行うには、XCADDY_GO_BUILD_FLAGS環境変数をXCADDY_GO_BUILD_FLAGS$-ldflags -w -s -extldflags \-Wl,-z,stack-size0x80000\のように変更してください アプリの要件に応じてスタックサイズの値を変更してください。-extldflags -Wl,-z,stack-size0x80000はリンカldに対してスレッドのスタックサイズを 0x80000512 KiBに引き上げる指示です。エラー文言の「during compilation」は、Symfony のコンパイルキャッシュ生成時に式が深すぎてスタックを消費することを示しており、値を0x100000などへ増やすことで回避できます。xcaddy を使用しない場合代替として、xcaddyを使わずにgoコマンドを直接使って FrankenPHP をコンパイルすることも可能ですcurl -L https://github.com/php/frankenphp/archive/refs/heads/main.tar.gz | tar xz cd frankenphp-main/caddy/frankenphp CGO_CFLAGS$(php-config --includes) CGO_LDFLAGS$(php-config --ldflags) $(php-config --libs) go build -tagsnobadger,nomysql,nopgxこの方法では、caddy/frankenphp/main.go にあるとおり、github.com/caddyserver/caddy/v2/modules/standard、github.com/dunglas/frankenphp/caddy、mercure、vulcain がデフォルトで組み込まれます。拡張モジュールを足したい場合はmain.goへの import 追加が別途必要になるため、通常は xcaddy の方が便利です。リポジトリ内のビルド補助スクリプトgo.shリポジトリには、公式ビルドでも使われている補助スクリプト go.sh が同梱されています。内容を確認すると、次のことを自動化しているのが分かりますGOFLAGSに-tagsnobadger,nomysql,nopgxを付与Caddy の不要なストレージバックエンドを除外CGO_CFLAGSにphp-config --includesと mtls-cflags.sh の出力AArch64 向け TLS モデル最適化フラグを連結CGO_LDFLAGSにphp-config --ldflagsとphp-config --libsを連結公式 Dockerfile でも../../go.sh install -ldflags -w -s -X github.com/caddyserver/caddy/v2.CustomVersionFrankenPHP ...という形でこのスクリプトを利用し、さらにsetcap cap_net_bind_serviceep /usr/local/bin/frankenphpで 80/443 ポートへのバインド権限を付与しています。手動ビルドで同様のバージョン情報を埋め込みたい場合は、この-ldflagsのパターンを参考にするとよいでしょう。静的ビルドへの切り替え配布やコンテナ化を重視する場合は、PHP・Caddy・FrankenPHP を 1 つのバイナリにまとめる静的ビルドも選択肢です。詳細は docs/ja/static.md を参照してください。リポジトリには static-builder-musl.Dockerfile完全静的、musl ベースと static-builder-gnu.Dockerfileほぼ静的、glibc ベース、動的拡張ロード可が用意され、docker-bake.hcl のstatic-builder-musl/static-builder-gnuターゲットからdocker buildx bake --load static-builder-muslのように起動できます。このときXCADDY_ARGSをカスタマイズしない場合、デフォルトで cbrotli・mercure・vulcain の 3 モジュールが含まれます両 Dockerfile のARG XCADDY_ARGSのデフォルト値。値を上書きする際は、必要なモジュールを明示的に列挙してください。また、build-static.shはPHP_VERSION・PHP_EXTENSIONS・PHP_EXTENSION_LIBS・FRANKENPHP_VERSION・EMBED・DEBUG_SYMBOLS・COMPRESSUPX・MIMALLOC・RELEASEなどの環境変数によるカスタマイズに対応しています。ビルド結果の検証ビルドが完了したら、生成されたバイナリが正しく構成されているか確認しましょう。公式 Docker イメージのビルド工程では、以下のコマンドで検証していますDockerfilefrankenphp version frankenphp build-infofrankenphp versionで FrankenPHP・PHP・Caddy の各バージョンが、frankenphp build-infoでビルド時に埋め込まれた拡張・モジュール情報が確認できます。ローカルで動作確認する場合は、package/Caddyfileや caddy/frankenphp/Caddyfile を参考に Caddyfile を用意し、./frankenphp run --config /path/to/Caddyfile --adapter caddyfileで起動してください。まとめ本記事では、FrankenPHP をソースからビルドする手順を、PHP の導入Homebrew / ソースコンパイル→ オプション依存関係の確認 → xcaddyまたはgo buildによる最終バイナリの組み立てという流れで解説しました。ポイントを整理するとPHP 8.2 以上かつ ZTS ビルドのlibphpが必須。--enable-embed・--enable-zts・--disable-zend-signalsの 3 フラグは外せません。CGO_CFLAGS/CGO_LDFLAGSはphp-configから導出します。CGO_ENABLED1を忘れないこと。xcaddy が推奨。--withで frankenphp/caddy・mercure・vulcain に加えて任意のモジュールを追加できます。不要な機能Brotli・watcherはビルドタグnobrotli/nowatcherで無効化可能です。完全な移植性が必要なら docs/ja/static.md の静的ビルドを検討してください。配布用のバージョン情報を埋め込む場合は、Dockerfile の-ldflags -X github.com/caddyserver/caddy/v2.CustomVersionFrankenPHP ...パターンをそのまま流用できます。自分の拡張セットに合わせて、FrankenPHP バイナリを自在にカスタマイズしてみてください。【免费下载链接】frankenphp The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Instructor 首次结构化抽取实战:用 Pydantic 模型从 LLM 中提取可用数据

Instructor 首次结构化抽取实战:用 Pydantic 模型从 LLM 中提取可用数据

Instructor 首次结构化抽取实战:用 Pydantic 模型从 LLM 中提取可用数据 【免费下载链接】instructor structured outputs for llms 项目地址: https://gitcode.com/GitHub_Trending/in/instructor 本教程是 Instructor 结构化输出的入门第一课:…

2026/11/13 18:39:43 阅读更多 →
wigolo 提取器插件开发指南:3步接入自己的内容解析逻辑

wigolo 提取器插件开发指南:3步接入自己的内容解析逻辑

wigolo 提取器插件开发指南:3步接入自己的内容解析逻辑 【免费下载链接】wigolo The go-to web for your AI coding agent — local-first search, fetch, crawl & research over MCP. No API keys, no cloud, $0/query. Public beta. 项目地址: https://gitc…

2026/11/13 18:39:43 阅读更多 →
Escrcpy 实用指南:三步配好安卓投屏、远程控制与文件传输

Escrcpy 实用指南:三步配好安卓投屏、远程控制与文件传输

Escrcpy 实用指南:三步配好安卓投屏、远程控制与文件传输 【免费下载链接】escrcpy 📱 Display and control your Android device graphically with scrcpy. 项目地址: https://gitcode.com/GitHub_Trending/es/escrcpy Escrcpy 是一款基于 scrcp…

2026/11/11 6:54:53 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/13 5:13:25 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/13 5:13:25 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/13 5:13:25 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/12 18:22:26 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/12 18:22:25 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/13 5:13:25 阅读更多 →

日新闻

周新闻

月新闻