インストール
OxPHP は Docker イメージとして配布されており、PHP アプリケーションの配信を始めるうえで最速かつ推奨される方法です。このイメージには、サーバーバイナリ、PHP 8.4 または 8.5 ZTS、OxPHP 拡張、そして Alpine Linux 上のすべてのランタイム依存関係が同梱されています。デフォルトの :0.13.0 および :latest タグには PHP 8.5 が含まれます。PHP 8.4 を取得するには、:0.13.0-php8.4、:php8.4、または任意の *-php8.4* タグバリアントを使用してください。
Docker(推奨)
GitHub Container Registry から公式イメージを取得します。
docker pull ghcr.io/oxphp/oxphp:0.13.0このイメージには以下が含まれます。
- OxPHP サーバーバイナリ — 非同期 HTTP サーバー
- PHP ZTS ランタイム — 取得したタグに応じて 8.4 または 8.5。マルチワーカー実行のためのスレッドセーフな PHP
- OxPHP PHP 拡張(
oxphp_sapi.so) —oxphp_request_id()、oxphp_server_info()、oxphp_worker()などの組み込み関数を提供します - ブリッジライブラリ(
liboxphp_bridge.so) — Rust サーバーと PHP ランタイムを接続します - Alpine Linux ベース — 最小限のランタイムフットプリント(Debian ビルドはナイトリーで公開されています。Debian(glibc)イメージを参照)
USERディレクティブなし — このイメージは特権ポートをバインドできるように root として 起動 します(nginx:alpine/php-fpm:alpine/frankenphp:alpineと同様)。ただしoxphp serve/runは配信を開始する前にデフォルトでwww-dataへ降格するため、トラフィックが最初から root として処理されることはありません。www-dataユーザー(UID 82、GID 82。Debian イメージでは 33)はあらかじめ作成されており、ビルド時に/var/www/htmlの所有者がこのユーザーに変更されます。特定の uid を指定したい場合や多層防御を強化したい場合は、オーケストレーターのレベルでランタイムの実行 ID を明示的に固定してください。docker run --user www-data ghcr.io/oxphp/oxphp:0.13.0- Compose:
services.app.user: www-data - Kubernetes:
securityContext.runAsUser: 82
Debian(glibc)イメージ
ナイトリーのパイプラインでは、同じサーバーを Alpine ではなく Debian trixie 上でビルドしたものも公開しています。タグは ghcr.io/oxphp/oxphp:nightly-trixie(PHP 8.4)、:php8.4-nightly-trixie、:php8.5-nightly-trixie で、linux/amd64 と linux/arm64 向けに提供されます。
タグ付きリリースは Alpine のみです。ナイトリータグは、前回の完全に成功した実行以降に main が進んだ夜に main からビルドされ、安定性の保証はありません。Debian のビルドが失敗した夜には、:nightly-trixie と :php<minor>-nightly-trixie は最後に成功したビルドのまま残るため、:nightly より遅れることがあります。
Debian イメージは、次の 2 つの理由により、リクエストあたりの CPU 消費が少なくなります。
- スレッドローカルストレージ。 スレッドセーフな PHP は、スレッドローカルなポインターを介してエンジンのスレッドごとの状態にアクセスします。musl に対してビルドされた PHP はそのポインターを global-dynamic TLS モデルのままにするため、
libphp.so内のコードは TLS ランタイムの呼び出しを通じてそれにアクセスします。glibc に対しては initial-exec を使い、スレッドポインターからの相対ロードで済みます。 - アロケーター。 musl のアロケーターは、PHP 自身のメモリマネージャーとは別に、拡張や libpq などのライブラリが使用するものです。これは libpq のクエリ結果のために新しいメモリをマップし、解放時にアンマップします。x86-64 では、これがサーバーのスレッド全体にわたる TLB シュートダウンのコストになります。
レスポンスあたりの OxPHP コンテナの CPU 時間を、同じ OxPHP リビジョンと PHP 8.5 パッチのもとで Debian イメージと Alpine イメージで比較したものです。対象は wrk -c64 で負荷をかけた Yii3 アプリケーションで、交互に行った 6 回の実行の中央値です。各行は 1 つのホストで計測しました。x86-64 は 16 vCPU のクラウド VM(AMD EPYC 9575F)、arm64 は Apple シリコン上の Docker Desktop です。Postgres 自身の CPU は含まれていません。
| Yii3 のページ | Postgres を読み込むページ | |
|---|---|---|
| x86-64、従来モード | −18.9% | −14.1% |
| x86-64、ワーカーモード | −18.1% | −18.6% |
| arm64、従来モード | −8.5% | −9.0% |
これをベースにビルドする Dockerfile で変わる点:
- パッケージは
apkではなくapt-get update && apt-get install -y --no-install-recommendsで、Debian のパッケージ名で導入します。たとえばintlとpdo_pgsqlのビルドにはlibicu-devとlibpq-dev、ランタイムにはlibicu76とlibpq5を使います。 - 拡張は
php:<minor>-zts-trixieステージでビルドします。-zts-alpineステージで musl に対してビルドされた.soはこのイメージと互換性がなく、その逆も同様です。 www-dataの UID/GID は 82 ではなく 33 です。securityContext.runAsUser: 33とし、数値で chown しているものはすべて 33 を使う必要があります。wgetはありませんが、curlはあります。Alpine イメージ向けにwget --spider http://localhost:9090/healthと書いたヘルスチェックは、curl -fsS -o /dev/null http://localhost:9090/healthになります。- イメージは大きくなります。PHP ベースは圧縮時で約 170〜180 MiB あり、Alpine の約 45〜50 MiB を上回ります。
イメージ構造
ランタイムイメージのファイルレイアウト:
/usr/local/
├── bin/
│ └── oxphp # server binary
├── lib/
│ ├── libphp.so # PHP ZTS runtime (8.4 or 8.5, matches the image tag)
│ ├── liboxphp_bridge.so # C bridge library
│ └── php/extensions/no-debug-zts-<ABI>/
│ ├── oxphp_sapi.so # OxPHP PHP extension
│ └── sodium.so, ... # from the PHP base image; the set depends on the tag
└── etc/php/
└── conf.d/
├── docker-php-ext-*.ini # from the PHP base image; the set depends on the tag
└── extension.ini # extension=oxphp_sapi.so<ABI> の値は PHP のマイナーバージョンによって異なります。 PHP 8.4 は 20240924 を使用し、PHP 8.5 は 20250925 を使用します。以下の例が 20250925 を固定しているのは、FROM 行がデフォルトの :0.13.0 タグの PHP である php:8.5-zts-alpine3.23 を対象としているためです。FROM を切り替える場合は、日付も切り替える必要があります。ビルド内で移植性のある形で導出するには:
php -r 'echo ini_get("extension_dir");'
# /usr/local/lib/php/extensions/no-debug-zts-20250925ハードコーディングを避けるため、シェルコマンド内では $(php -r 'echo ini_get("extension_dir");') を使用してください。
このイメージには独自の php.ini は含まれておらず(/usr/local/etc/php/ には conf.d/ のほか、アップストリームのサンプルである php.ini-development と php.ini-production があるだけで、PHP はどちらも読み込みません)、アプリケーション向けの設定も入っていません。設定は conf.d 配下の .ini ファイルとして、マウントするかコピーして用意してください。Docker ガイド を参照してください。
.ini が読み込まれるかどうか、またいつ読み込まれるかはファイル名で決まります。PHP は conf.d 内のすべての .ini ファイルをアルファベット順に解析し、それ以外の名前のファイルは何も通知せずにスキップします。通常の設定では最後に読み込まれた値が有効になるため、設定を上書きするファイルは、その設定を定義するファイルより後ろにソートされる名前にする必要があります。一方、extension= と zend_extension= はすべてのファイルから収集されてすべて読み込まれるため、後の extension= が前のものを置き換えることはありません。
OxPHP の 3 つのコンポーネントとその目的です。サイズは 0.11.0 イメージで計測したものです。サイズは linux/amd64 と linux/arm64 で異なり、リリースごとにも変わります。
| コンポーネント | サイズ | 目的 |
|---|---|---|
oxphp |
約 12〜15 MB | HTTP サーバー、ルーティング、プラグイン、メトリクス |
liboxphp_bridge.so |
約 150〜170 KB | サーバーを PHP ランタイムに接続する共有ブリッジライブラリ |
oxphp_sapi.so |
約 700 KB | PHP 関数(oxphp_request_id()、OxPHP\Http\Request など) |
依存関係チェーン:
graph LR oxphp["oxphp"] --> libphp["libphp.so"] libphp --> deps["libxml2, libcurl, libsqlite3, libonig, ..."] oxphp --> bridge["liboxphp_bridge.so"] sapi["oxphp_sapi.so"] --> bridge
oxphp バイナリは libphp.so と liboxphp_bridge.so にリンクします。PHP 拡張 oxphp_sapi.so もブリッジライブラリにリンクしており、これによりリクエストごとの状態が PHP コードから利用できるようになります。
最小構成の Dockerfile
ベースイメージ php:8.5-zts-alpine3.23(または php:8.4-zts-alpine3.23)には、libphp.so とそのすべての依存関係がすでに含まれています。FROM の PHP マイナーバージョンは、コピー元の OxPHP タグに合わせてください。C ライブラリも同様で、-trixie タグの成果物は Alpine ベースではなく php:<minor>-zts-trixie に載せます。必要なのは、3 つの OxPHP 成果物をコピーし、libgcc を追加することだけです。libgcc は Rust でビルドされた oxphp バイナリがリンクしているライブラリで、Alpine の PHP イメージには含まれていません。
FROM php:8.5-zts-alpine3.23
RUN apk add --no-cache libgcc
COPY --from=ghcr.io/oxphp/oxphp:0.13.0 /usr/local/bin/oxphp /usr/local/bin/oxphp
COPY --from=ghcr.io/oxphp/oxphp:0.13.0 /usr/local/lib/liboxphp_bridge.so /usr/local/lib/
COPY --from=ghcr.io/oxphp/oxphp:0.13.0 /usr/local/lib/php/extensions/no-debug-zts-20250925/oxphp_sapi.so /usr/local/lib/php/extensions/no-debug-zts-20250925/
RUN echo "extension=oxphp_sapi.so" > /usr/local/etc/php/conf.d/oxphp.ini
COPY --chown=www-data:www-data . /var/www/html/public
EXPOSE 80 443
CMD ["oxphp"]この方法は開発に便利です。PHP CLI、docker-php-ext-install、pecl がすべて利用できます。Composer と Xdebug は PHP ベースイメージには含まれていません。Docker ガイド の dev ターゲットと同様に、COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer と pecl install xdebug で自分で追加してください。
本番用の Dockerfile
公式の OxPHP イメージは、ベースとなっている php:<minor>-zts-alpine3.23 イメージの PHP CLI と拡張ツール(php、phpize、pecl、docker-php-ext-install)を保持しているため、その中で直接拡張をインストールできます。本番環境での PHP 拡張機能のインストールを参照してください。代わりに別のステージで拡張をビルドすれば、icu-dev のようなビルド専用のパッケージを最終イメージから除外できます。追加の PHP 拡張が必要かどうかによって、次の 2 つのビルドのどちらを選ぶかが決まります。
アプリケーションが追加の拡張(pdo_mysql、intl など)を必要とする場合は、別のステージでビルドし、最終イメージにコピーします。
# Extension build stage
FROM php:8.5-zts-alpine3.23 AS extensions
RUN apk add --no-cache icu-dev postgresql-dev \
&& docker-php-ext-install pdo pdo_mysql pdo_pgsql intl
# Production
FROM ghcr.io/oxphp/oxphp:0.13.0
# Runtime dependencies for extensions
USER root
RUN apk add --no-cache icu-libs libpq
# Copy compiled extensions
COPY --from=extensions /usr/local/lib/php/extensions/no-debug-zts-20250925/*.so /usr/local/lib/php/extensions/no-debug-zts-20250925/
# Enable extensions
RUN { \
echo "extension=pdo.so"; \
echo "extension=pdo_mysql.so"; \
echo "extension=pdo_pgsql.so"; \
echo "extension=intl.so"; \
} > /usr/local/etc/php/conf.d/app-extensions.ini
USER www-data
COPY --chown=www-data:www-data . /var/www/html/publicアプリケーションが追加の拡張を必要としない場合は、これで十分です。
FROM ghcr.io/oxphp/oxphp:0.13.0
COPY --chown=www-data:www-data . /var/www/html/publicビルドして実行します。
docker build -t my-app .
docker run -p 80:80 my-appサーバーはデフォルトでポート 80 をリッスンします。ドキュメントルートは /var/www/html/public で、上記のスニペットはプロジェクトをそこへ直接コピーしています。すでに public/ サブディレクトリを持つ Laravel、Symfony、その他のフレームワークでは、代わりに COPY --chown=www-data:www-data . /var/www/html を使用し、フレームワーク自身の public/ がデフォルトと一致するようにしてください。構成がさらに異なる場合は、DOCUMENT_ROOT 環境変数でドキュメントルートを上書きしてください。
ソースビルド(PHP なし)
PHP 機能を無効にして OxPHP をソースからビルドすると、静的ファイルのみを配信できます。
cargo build --release --no-default-featuresバイナリは target/release/oxphp にあります。このモードでは、静的ファイルは通常どおり配信しつつ、PHP リクエストにはプレースホルダーレスポンスを返すスタブエグゼキュータが使用されます。PHP ランタイムが存在しない状態でサーバーをテストするのに便利です。
ソースビルド(PHP あり)
完全な PHP サポートを備えた OxPHP をビルドするには、まずブリッジライブラリと PHP 拡張をコンパイルしてインストールする必要があります。
前提条件
- Rust ツールチェーン(1.91.1 以降)
- ZTS(Zend Thread Safety)を有効にした PHP 8.4 または 8.5
- C コンパイラ(gcc または clang)
phpizeと PHP 開発ヘッダー
ビルド手順
-
ブリッジライブラリをビルドしてインストールします。
cd ext/bridge make && sudo make install -
PHP 拡張をビルドしてインストールします。
cd ../ phpize && ./configure --enable-oxphp-sapi && make && sudo make install -
OxPHP をビルドします。 デフォルトの機能には php が含まれます。
cargo build --release
このバイナリは、実行時にライブラリ検索パス上の共有ライブラリを必要とします。
export LD_LIBRARY_PATH=/usr/local/lib
./target/release/oxphpAlpine Linux にデプロイする場合は、PHP ランタイムに使用するのと同じ php:{8.4,8.5}-zts-alpine イメージ内でビルドしてください。出荷する OxPHP イメージのマイナーバージョンに合わせます。glibc と musl のビルドを混在させると、実行時エラーが発生します。公式の Docker イメージはこれを正しく処理します。
インストールの確認
OxPHP を起動すると、構造化された JSON ログ出力によってサーバーが稼働していることを確認できます。
{"timestamp":"...","level":"INFO","message":"OxPHP HTTP server starting","listen_addr":"0.0.0.0:80",...}
{"timestamp":"...","level":"INFO","message":"Server listening","addr":"0.0.0.0:80"}サーバーが応答することをテストします。
curl http://localhost/INTERNAL_ADDR で内部サーバーを有効にした場合は、ヘルスエンドポイントを確認します。
curl http://localhost:9090/health正常なサーバーは 200 と JSON ステータスを返します。劣化したサーバーは 503 を返します。
次のステップ
- クイックスタート — プロジェクトを作成し、Docker Compose で OxPHP を実行して、最初のリクエストを送ります
- Docker ガイド — 開発用と本番用の Dockerfile、Compose の設定、ボリュームマウント
- 設定 — 環境変数の完全なリファレンス