部署示例

这些指南展示了如何在 OxPHP 上运行九款主流 PHP 应用,每一款都是一个独立自包含的 Docker Compose 项目。每个方案都经过端到端的构建与验证:店铺前台、管理后台、静态资源以及 OxPHP 内部健康检查端点全部返回 200

每个页面都是一份完整、可直接复制粘贴的方案:一份 Dockerfile、一份 docker-compose.yml、安装命令,以及应用自带文档(那些针对 nginx + PHP-FPM 编写的文档)未曾涵盖的 OxPHP 专属细节。

涉及的应用

应用 类型 路由模式 PHP 额外服务 安装方式
Laravel 框架 框架模式 8.5 MySQL composer create-project
Symfony 框架 框架模式 8.5 composer create-project
Yii3 框架 框架模式 8.5 composer create-project
WordPress CMS 传统模式 8.5 MySQL WP-CLI
Drupal CMS 框架模式 8.4 MySQL drush site:install
Craft CMS CMS 框架模式 8.5 MySQL craft install
October CMS CMS 框架模式 + 镜像 8.4 MySQL october:migrate + 镜像
Magento 电商 框架模式 8.4 MySQL + OpenSearch bin/magento setup:install
OpenCart 电商 传统模式 8.4 MySQL CLI 安装程序

每个方案的共通之处

基于官方发布的 OxPHP 镜像构建

OxPHP 以 ghcr.io/oxphp/oxphp 的形式提供了一个开箱即用的 PHP 运行时(默认 PHP 8.5;PHP 8.4 变体则以 ghcr.io/oxphp/oxphp:<ver>-php8.4-alpine<X> 的形式发布)。该发布镜像中已经包含 oxphp 二进制文件、libphp.so、OxPHP SAPI 扩展、PHP CLI,以及对 Composer 友好的工具链。这些方案以下面两种形态之一对其进行扩展:

  1. 将 OxPHP 拷贝进 php:*-zts-alpine 基础镜像(Laravel、Symfony、Yii3、Craft、Magento、OpenCart、Drupal、October 采用此方式)。一次多阶段构建从四个阶段组装出一个 dev 镜像:

    Dockerfile
    FROM php:8.4-zts-alpine3.23 AS php-base # your app's PHP extensions FROM composer:2 AS composer # the Composer binary FROM ghcr.io/oxphp/oxphp:0.10.0-php8.4-alpine3.23 AS oxphp # OxPHP artifacts FROM php-base AS dev # final image # ... copy the oxphp binary, bridge library, and SAPI extension across: COPY --from=oxphp /usr/local/bin/oxphp /usr/local/bin/oxphp COPY --from=oxphp /usr/local/lib/liboxphp_bridge.so /usr/local/lib/ COPY --from=oxphp /usr/local/lib/php/extensions/ /tmp/oxphp-ext/ RUN cp /tmp/oxphp-ext/*/oxphp_sapi.so "$(php -r 'echo ini_get("extension_dir");')/" \ && echo "extension=oxphp_sapi.so" > /usr/local/etc/php/conf.d/oxphp-ext.ini
  2. 直接扩展 OxPHP 运行时(WordPress 采用此方式)。一个构建阶段针对匹配的 php:*-zts-alpine 编译扩展,并将 .so 文件放入 OxPHP 镜像中。

Note

无论采用哪种方式,PHP ABI 都必须匹配。OxPHP 镜像的 libphp.sooxphp_sapi.so 是针对某一个 PHP 版本编译的(例如 8.4 → no-debug-zts-20240924);php-base/构建阶段必须使用相同的 php:<X.Y>-zts-alpine<Z>,这样你编译出的扩展才能保持 ABI 兼容。混用版本会导致 oxphp_sapi.so 拒绝加载,或在启动时破坏 musl TLS。

规范的多阶段模板请参见 Docker 指南,仓库中的 examples/dockerfile/ 则提供了一份可直接复制的版本。

慎重选择 PHP 版本

默认的 ghcr.io/oxphp/oxphp:<ver> 镜像是 PHP 8.5。对现代框架(Laravel、Symfony、Yii3、Craft)而言,这没有问题。而更老或更保守的代码库 —— Magento、OpenCart、Drupal、October CMS —— 则通过 …-php8.4-alpine… 标签固定到 PHP 8.4,因为它们的组件栈早于 8.5,在 8.5 上会抛出弃用警告。每个方案都会说明自己使用哪个版本以及原因。

根据应用的形态选择路由模式

OxPHP 的路由模式可以直接映射到应用的目录布局方式:

  • 框架模式ENTRY_FILE=index.php)—— 在 public/(或 web/pub/)目录下有一个统一的前端控制器;已存在的静态文件从磁盘直接提供,其余一切都分发给 index.php。适用于 Laravel、Symfony、Yii3、Craft、Magento、Drupal、October。
  • 传统模式(不设置 ENTRY_FILE)—— 存在多个物理 PHP 入口点(例如 index.php 加上一个 admin/ 目录),作为真实文件提供。适用于 WordPress 和 OpenCart。

在同一个容器中完成安装

dev 镜像自带 PHP CLI 和 Composer(并视情况附带 drushwpbin/magentophp yiiphp craftphp artisan),因此每一条安装与维护命令都在运行中的容器内执行 —— 无需额外的工具链:

bash
docker compose exec app php artisan migrate # Laravel docker compose exec app vendor/bin/drush cr # Drupal docker compose run --rm app composer install # any

处处适用的安全默认设置

OxPHP 免费为你提供了若干项保护,而 nginx + PHP-FPM 则需要显式配置才能获得:

  • 点路径拦截 —— .env.git/.htaccess 以及任何其他以点号开头的路径段无需配置即返回 404。正因如此,从一个同时包含 .env 的目录运行应用也不会泄露它。
  • PHP 执行拒绝列表PHP_DENY_PATHS)—— 由传统模式的方案使用:OpenCart 拦截 system/install/ 脚本;WordPress 拦截 wp-content/uploads/ 下的 .php 执行。(在框架模式下这是个空操作,因为任意 .php 永远不会被直接执行。)
  • 符号链接允许路径SYMLINK_ALLOW_PATHS)—— 由 October CMS 使用,以便 OxPHP 跟随 october:mirror public 生成的资源符号链接,同时在其他任何地方仍然拦截符号链接逃逸。

各个方案

这些页面按应用类型分组,与目录布局保持一致:

text
examples/ ├── framework/ # Laravel, Symfony, Yii3 ├── cms/ # WordPress, Drupal, Craft, October └── ecommerce/ # Magento, OpenCart

框架 —— framework/

  • Laravel —— 框架模式应用的典范
  • Symfony —— 极简骨架,无数据库
  • Yii3 —— 所有方案中最精简的;仅核心扩展

CMS —— cms/

  • WordPress —— 传统模式、运行时扩展构建、WP-CLI 边车容器
  • Drupal —— 框架模式、PDO + drush
  • Craft CMS —— 框架模式、由控制台驱动的安装
  • October CMS —— 框架模式,配合 public/ 镜像与 SYMLINK_ALLOW_PATHS

电商 —— ecommerce/

  • Magento —— 最重量级的一个:OpenSearch、PHP 8.4、静态资源版本符号链接
  • OpenCart —— 传统模式,包含两个前端控制器与 PHP_DENY_PATHS