快速开始

OxPHP 官方镜像内置了服务器、PHP、OxPHP 扩展以及全部运行时依赖, 因此你只需几条命令就能从一个空目录跑起一个应用。

一条命令

如果你已经有一个带 public/ 目录的 PHP 项目:

bash
docker run -p 80:80 -v .:/var/www/html ghcr.io/oxphp/oxphp:0.10.0

打开 http://localhost/。你的应用已经在运行了。

要启用内部服务器(健康检查、指标、配置):

bash
docker run -p 80:80 -p 9090:9090 -e INTERNAL_ADDR=0.0.0.0:9090 -v .:/var/www/html ghcr.io/oxphp/oxphp:0.10.0

使用 Docker Compose 逐步搭建

一个更详细的演练,从一个空目录到一个带有健康检查和结构化日志的可用 PHP 应用。

  1. 创建项目目录。

    bash
    mkdir my-oxphp-app && cd my-oxphp-app
  2. 创建一个 Dockerfile。

    Dockerfile
    FROM ghcr.io/oxphp/oxphp:0.10.0 COPY --chown=www-data:www-data . /var/www/html

    官方镜像包含了服务器二进制文件、PHP 8.4 或 8.5 ZTS(默认为 8.5;用 :0.10.0-php8.4 或任意 *-php8.4* 标签拉取 8.4)、OxPHP PHP 扩展以及所有运行时依赖。

  3. 添加一个 compose.yaml。

    compose.yaml
    services: oxphp: build: . ports: - "80:80" - "9090:9090" environment: - LISTEN_ADDR=0.0.0.0:80 - DOCUMENT_ROOT=/var/www/html/public - INTERNAL_ADDR=0.0.0.0:9090 - LOG_LEVEL=info - ACCESS_LOG=all

    端口 80 用于对外提供你的应用。端口 9090 暴露内部服务器,用于健康检查、 Prometheus 指标以及查看当前生效的配置快照。

  4. 创建一个 PHP 应用。

    bash
    mkdir -p public

    创建 public/index.php

    public/index.php
    <?php $requestId = oxphp_request_id(); $info = oxphp_server_info(); echo "<h1>OxPHP</h1>\n"; echo "<p>Request ID: {$requestId}</p>\n"; echo "<p>Worker: {$info['worker_id']}</p>\n"; echo "<p>SAPI: " . php_sapi_name() . "</p>\n"; echo "<p>Version: {$info['version']}</p>\n"; echo "<p>Time: " . date('c') . "</p>\n";

    oxphp_request_id() 返回分配给每个请求的唯一 ID。oxphp_server_info() 返回 正在运行的服务器的详细信息,包括 versionworker_idrequest_timeworker_mode

  5. 构建并启动。

    bash
    docker compose up -d --build
  6. 测试你的应用。

    bash
    curl http://localhost/

    预期输出:

    html
    <h1>OxPHP</h1> <p>Request ID: 67a4b3c11a2b00000001</p> <p>Worker: 0</p> <p>SAPI: cli-server</p> <p>Version: 0.10.0</p> <p>Time: 2026-03-23T12:00:00+00:00</p>

    每个请求都会获得一个唯一 ID。worker ID 显示是哪个 PHP 工作进程线程处理了它。

  7. 检查内部端点。

    bash
    # 健康检查 —— 健康时返回 200,降级时返回 503 curl http://localhost:9090/health # 兼容 Prometheus 的指标 curl http://localhost:9090/metrics # 当前生效的配置(TLS 路径已脱敏) curl http://localhost:9090/config
  8. 查看日志。

    bash
    docker compose logs -f oxphp

    由于设置了 ACCESS_LOG=all,每个请求都会以一行结构化 JSON 日志的形式出现, 包含方法、路径、状态码、响应时间和请求 ID。

Tip

如果你的应用需要自定义 PHP 扩展(pdo_pgsql、intl、xdebug 等),请参阅仓库中的 examples/dockerfile/Dockerfile。 它是一个开箱即用的多阶段 Dockerfile,分别包含 devprod 两个目标。

为什么 `php_sapi_name()` 报告的是 `cli-server` 而不是 `oxphp`?

OxPHP 特意注册为 OPcache 能识别的 SAPI 名称之一。OPcache 会对未知的 SAPI 禁用自身; 如果不做这个重命名,PHP 执行会完全跳过 OPcache 层,速度会慢上好几倍。代价是 php_sapi_name() 无法用来检测 OxPHP —— 请改用 function_exists('oxphp_request_id')OxPHP\Http\Request::current()

下一步

  • Docker 指南 —— 开发与生产环境的 Dockerfile、Compose 配置、PHP ini 挂载以及健康检查设置
  • 配置 —— 完整的环境变量参考
  • 路由 —— Traditional、Framework、SPA 和 Worker 四种路由模式
  • 工作进程模式 —— 只引导一次即可处理多个请求的持久化 PHP 进程
  • PHP 函数 —— 所有 OxPHP 内置 PHP 函数