安装

OxPHP 以 Docker 镜像的形式分发,这是开始为 PHP 应用提供服务最快、也最推荐的方式。该镜像在 Alpine Linux 上打包了服务器二进制文件、PHP 8.4 或 8.5 ZTS、OxPHP 扩展以及全部运行时依赖。默认的 :0.10.0:latest 标签附带 PHP 8.5;如需 PHP 8.4,请拉取 :0.10.0-php8.4:php8.4 或任意 *-php8.4* 标签变体。

Docker(推荐)

从 GitHub Container Registry 拉取官方镜像:

bash
docker pull ghcr.io/oxphp/oxphp:0.10.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 基础镜像 —— 最小化的运行时体积
  • USER 指令 —— 镜像以 root 身份启动(与 nginx:alpine / php-fpm:alpine / frankenphp:alpine 一致),以便绑定特权端口,但随后 oxphp serve/run 会在提供服务前默认降权到 www-data,因此开箱即用时流量不会以 root 身份处理。www-data 用户(UID 82,GID 82)已预先创建,且构建时 /var/www/html 已 chown 给它。如需指定特定 uid 或额外的纵深防御,请在编排层显式固定运行时身份:
    • docker run --user www-data ghcr.io/oxphp/oxphp:0.10.0
    • Compose:services.app.user: www-data
    • Kubernetes:securityContext.runAsUser: 82

镜像结构

运行时镜像的文件布局:

text
/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 ├── etc/php/ │ └── conf.d/ │ ├── custom.ini # PHP settings for OxPHP │ └── oxphp.ini # extension=oxphp_sapi.so
Note

<ABI> 的值取决于 PHP 的次版本号。 PHP 8.4 使用 20240924,PHP 8.5 使用另一个日期戳。下面的示例固定使用 20240924,是因为它们的 FROM 行以 php:8.4-zts-alpine3.23 为目标 —— 一旦切换 FROM,就必须同时切换该日期。若要在构建过程中可移植地推导出它:

bash
php -r 'echo ini_get("extension_dir");' # /usr/local/lib/php/extensions/no-debug-zts-20240924

在 shell 命令中使用 $(php -r 'echo ini_get("extension_dir");'),以避免硬编码。

OxPHP 的三个组件及其用途:

组件 大小 用途
oxphp ~8 MB HTTP 服务器、路由、插件、指标
liboxphp_bridge.so ~50 KB 将服务器链接到 PHP 运行时的共享桥接库
oxphp_sapi.so ~200 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.soliboxphp_bridge.so。PHP 扩展 oxphp_sapi.so 也链接到桥接库,从而使每个请求的状态可供你的 PHP 代码使用。

最小 Dockerfile

基础镜像 php:8.4-zts-alpine3.23(或 php:8.5-zts-alpine3.23)已经包含 libphp.so 及其全部依赖。请让 FROM 中的 PHP 次版本号与你所复制的 OxPHP 标签相匹配。你只需复制三个 OxPHP 构件:

Dockerfile
FROM php:8.4-zts-alpine3.23 COPY --from=ghcr.io/oxphp/oxphp:0.10.0 /usr/local/bin/oxphp /usr/local/bin/oxphp COPY --from=ghcr.io/oxphp/oxphp:0.10.0 /usr/local/lib/liboxphp_bridge.so /usr/local/lib/ COPY --from=ghcr.io/oxphp/oxphp:0.10.0 /usr/local/lib/php/extensions/no-debug-zts-20240924/oxphp_sapi.so /usr/local/lib/php/extensions/no-debug-zts-20240924/ 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、composerdocker-php-ext-installxdebug 都可用。详见 Docker 指南

生产环境 Dockerfile

官方 OxPHP 镜像是最小化的:它不包含 PHP CLI,也不包含扩展构建工具。你是否需要额外的 PHP 扩展,决定了应采用以下两种构建方式中的哪一种。

如果你的应用需要额外的扩展(pdo_mysql、intl 等),请在单独的构建阶段中编译它们,再复制到最终镜像中:

Dockerfile
# Extension build stage FROM php:8.4-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.10.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-20240924/*.so /usr/local/lib/php/extensions/no-debug-zts-20240924/ # 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

构建并运行:

bash
docker build -t my-app . docker run -p 80:80 my-app

服务器默认监听 80 端口。文档根目录为 /var/www/html/public,上面的代码片段直接将项目复制到其中。对于 Laravel、Symfony 或其他本身就带有 public/ 子目录的框架,请改用 COPY --chown=www-data:www-data . /var/www/html,让框架自带的 public/ 与默认目录对齐。如果你的目录结构差异更大,请用 DOCUMENT_ROOT 环境变量覆盖文档根目录。

源码构建(不含 PHP)

在禁用 PHP 功能的情况下从源码构建 OxPHP,仅提供静态文件服务:

bash
cargo build --release --no-default-features

二进制文件位于 target/release/oxphp。它使用一个桩执行器(stub executor),对 PHP 请求返回占位响应,同时正常提供静态文件服务。这种模式适合在没有 PHP 运行时的情况下测试服务器。

源码构建(含 PHP)

构建具备完整 PHP 支持的 OxPHP,需要先编译并安装桥接库和 PHP 扩展。

前置条件

  • Rust 工具链(1.91.1 或更高版本)
  • 启用了 ZTS(Zend Thread Safety,Zend 线程安全)的 PHP 8.4 或 8.5
  • C 编译器(gcc 或 clang)
  • phpize 和 PHP 开发头文件

构建步骤

  1. 构建并安装桥接库。

    bash
    cd ext/bridge make && sudo make install
  2. 构建并安装 PHP 扩展。

    bash
    cd ../ phpize && ./configure --enable-oxphp-sapi && make && sudo make install
  3. 构建 OxPHP。 默认功能包含 php。

    bash
    cargo build --release

该二进制文件在运行时要求共享库位于库搜索路径中:

bash
export LD_LIBRARY_PATH=/usr/local/lib ./target/release/oxphp
Note

在部署到 Alpine Linux 时,请在与 PHP 运行时相同的 php:{8.4,8.5}-zts-alpine 镜像中构建 —— 要与你所交付的 OxPHP 镜像的次版本号相匹配。混用 glibc 和 musl 构建会导致运行时错误。官方 Docker 镜像已正确处理这一点。

验证安装

启动 OxPHP 后,结构化的 JSON 日志输出可确认服务器正在运行:

text
{"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"}

测试服务器是否响应:

bash
curl http://localhost/

如果你通过 INTERNAL_ADDR 启用了内部服务器,请验证健康检查端点:

bash
curl http://localhost:9090/health

健康的服务器会返回 200 及 JSON 状态。降级的服务器会返回 503

下一步

  • 快速开始 —— 创建项目、用 Docker Compose 运行 OxPHP,并发起你的第一个请求
  • Docker 指南 —— 用于开发和生产的 Dockerfile、Compose 配置以及卷挂载
  • 配置 —— 完整的环境变量参考