在 FrankenPHP 中运行 Laravel 应用:Docker、本地安装、Octane 与独立二进制完整指南
【免费下载链接】frankenphp🧟 The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp
FrankenPHP 是一个基于 Caddy 构建的现代 PHP 应用服务器,它把 PHP 解释器、生产级 Web 服务器与自动 HTTPS 融为一体。本文以 Laravel 为具体落点,系统讲解四种运行与分发 Laravel 应用的方式:官方 Docker 镜像、本地二进制 + Caddyfile、基于 Worker 模式的 Laravel Octane 高性能运行,以及把整套 Laravel 应用打包成可独立执行的静态二进制。阅读本文后,你将掌握从开发到生产部署、再到离线分发的完整实战路径。
本文对应的仓库文档为 docs/es/laravel.md(英文原版见 docs/laravel.md),其中涉及的所有命令与配置均以当前仓库实际内容为准。
一、用 Docker 镜像快速启动 Laravel 应用
FrankenPHP 官方 Docker 镜像内置了 PHP、Caddy 以及默认的Caddyfile配置(见仓库中的 caddy/frankenphp/Caddyfile)。要运行一个 Laravel 项目,只需把项目目录挂载到容器的/app目录:
docker run -p 80:80 -p 443:443 -p 443:443/udp -v $PWD:/app dunglas/frankenphp从 Laravel 项目根目录执行该命令即可。命令中各部分的含义:
-p 80:80:映射 HTTP 端口;-p 443:443:映射 HTTPS 端口(Caddy 会自动为localhost签发本地证书,访问时使用https://localhost并接受自签名证书即可);-p 443:443/udp:映射 HTTP/3(QUIC)使用的 UDP 端口;-v $PWD:/app:把当前 Laravel 项目挂载到容器内的/app,而 caddy/frankenphp/Caddyfile 中默认的root指向public/,php_server指令会执行 PHP 文件并托管静态资源。
[!TIP] 该镜像自带的
Caddyfile还预留了SERVER_NAME、SERVER_ROOT、FRANKENPHP_CONFIG、CADDY_GLOBAL_OPTIONS等环境变量注入点,并注释了 Mercure 与 Vulcain 模块的启用方式。修改站点配置更推荐通过环境变量或Caddyfile.d/*.caddyfile附加文件实现,而不是直接改动镜像内配置。
二、本地安装:用 Caddyfile 运行 Laravel
不想使用 Docker 时,可以从官方发布的独立二进制入手。独立二进制自带 PHP 8.5 及多数常用扩展,Linux 版本为静态链接,无需安装任何系统依赖即可运行(详见 README.md)。
- 下载对应你系统的二进制;
- 在 Laravel 项目根目录创建
Caddyfile,写入以下配置:
# Caddyfile { frankenphp } # 你的服务器域名 localhost { # 把 Web 根目录设置为 public/ root public/ # 启用压缩(可选) encode zstd br gzip # 从 public/ 目录执行 PHP 文件并托管静态资源 php_server { try_files {path} index.php } }- 在 Laravel 项目根目录启动:
frankenphp run。
这段配置对应的行为在 docs/config.md 中有更底层的解释:php_server指令等价于一组 Caddy 路由——先为目录请求补尾部斜杠,再通过try_files依次尝试请求路径、{path}/index.php与index.php,把命中项重写为实际文件,最后把*.php请求交给 FrankenPHP、其余交给file_server托管。这也是 Laravel 单入口(public/index.php)能够正常工作的原因。
如果只是想快速演示或开发,也可以不写Caddyfile,直接使用php-server子命令(见 caddy/php-server.go):
frankenphp php-server --root public/三、Laravel Octane:把应用常驻内存
Laravel Octane 是 Laravel 官方的应用加速方案,它让应用只引导(bootstrap)一次并常驻内存,后续请求在毫秒级完成。FrankenPHP 的 Worker 模式正是 Octane 的底层支撑:应用在 PHP 线程中长期存活,请求到达时由frankenphp_handle_request()循环分发处理(工作机制详见 docs/worker.md)。
安装与启动:
composer require laravel/octanephp artisan octane:install --server=frankenphpoctane:install --server=frankenphp会在应用内生成 Octane 配置文件,并注册 FrankenPHP 服务器条目。启动命令为:
php artisan octane:frankenphpoctane:frankenphp命令支持的选项如下(默认值以 Laravel Octane 官方实现为准):
| 选项 | 作用 | 默认值 |
|---|---|---|
--host | 服务器绑定的 IP 地址 | 127.0.0.1 |
--port | 服务器监听端口 | 8000 |
--admin-port | Caddy 管理 API 端口 | 2019 |
--workers | 处理请求的 Worker 数量 | auto(自动探测) |
--max-requests | 每个 Worker 处理多少请求后重启(缓解内存泄漏) | 500 |
--caddyfile | 指定 FrankenPHP 的Caddyfile路径 | Laravel Octane 内置模板 |
--https | 启用 HTTPS、HTTP/2、HTTP/3,并自动签发与续期证书 | 关闭 |
--http-redirect | 启用 HTTP 到 HTTPS 的跳转(仅在传--https时生效) | 关闭 |
--watch | 应用文件变化时自动重启服务器 | 关闭 |
--poll | 跨网络监视文件时改用文件系统轮询 | 关闭 |
--log-level | 按指定级别记录日志,使用 Caddy 原生日志器 | 关闭 |
[!TIP] 需要结构化 JSON 日志(例如接入日志分析平台)时,务必显式传入
--log-level选项。
关于--max-requests,它对应 FrankenPHP 在 docs/config.md 中描述的max_requests机制:PHP 并非为长驻进程设计,库与旧代码存在内存泄漏风险时,可在线程处理指定数量请求后将其整体重启,清理全部内存与状态,重启期间其他线程继续服务。
四、把 Laravel 应用打包成独立二进制
利用 FrankenPHP 的应用嵌入特性(详见 docs/embed.md),可以把 Laravel 应用连同 PHP 解释器、Caddy Web 服务器打包进一个自包含的静态二进制,实现"一个文件分发一个应用"。
以 Linux 为例,按以下步骤操作:
1. 编写static-build.Dockerfile
在应用仓库中创建:
# static-build.Dockerfile FROM --platform=linux/amd64 dunglas/frankenphp:static-builder-gnu # 如果打算在 musl-libc 系统上运行,改用 static-builder-musl # 复制你的应用 WORKDIR /go/src/app/dist/app COPY . . # 删除测试等无关文件以减小体积 # 也可以把这些文件加入 .dockerignore RUN rm -Rf tests/ # 复制 .env 文件 RUN cp .env.example .env # 将 APP_ENV 与 APP_DEBUG 切换为生产配置 RUN sed -i'' -e 's/^APP_ENV=.*/APP_ENV=production/' -e 's/^APP_DEBUG=.*/APP_DEBUG=false/' .env # 按需修改 .env 的其他配置 # 安装依赖 RUN composer install --ignore-platform-reqs --no-dev -a # 编译静态二进制 WORKDIR /go/src/app/ RUN EMBED=dist/app/ ./build-static.sh[!CAUTION] 一些项目自带的
.dockerignore会忽略vendor/目录与.env文件,编译前务必调整或删除.dockerignore,否则构建出的二进制将不包含应用依赖。
2. 构建镜像
docker build -t static-laravel-app -f static-build.Dockerfile .3. 取出二进制
docker cp $(docker create --name static-laravel-app-tmp static-laravel-app):/go/src/app/dist/frankenphp-linux-x86_64 frankenphp ; docker rm static-laravel-app-tmp4. 填充缓存
frankenphp php-cli artisan optimize5. 执行数据库迁移(如有)
frankenphp php-cli artisan migrate6. 生成应用密钥
frankenphp php-cli artisan key:generate7. 启动服务器
frankenphp php-server应用即告就绪。这里用到的php-cli子命令在 caddy/php-cli.go 中实现:它把参数透传给 PHP 的 CLI SAPI 执行;当二进制内嵌了应用(frankenphp.EmbeddedAppPath非空)且脚本路径不是绝对路径时,会自动在嵌入目录中解析目标脚本,因此artisan等命令可以开箱即用。
如需为其他操作系统(如 macOS)构建,或想进一步定制扩展、PHP 版本,请参考 docs/embed.md 与 docs/static.md。
五、修改存储路径:适配内嵌应用的持久化
默认情况下,Laravel 会把上传文件、缓存、日志等写入应用内的storage/目录。这对内嵌应用并不合适——因为每次发布新版本,二进制会被解压到不同的临时目录,存储内容会随之丢失。
解决办法是把存储目录指向临时目录之外的固定位置:
- 设置环境变量
LARAVEL_STORAGE_PATH(例如写入.env); - 或在代码中调用
Illuminate\Foundation\Application::useStoragePath()方法。
二者任选其一,即可让数据库迁移、缓存与用户上传数据跨版本持久保存。
六、为 Laravel 应用接入 Mercure 实时推送
Mercure 是一种基于 HTTP 的实时事件推送协议,也是 WebSocket 的轻量替代方案,现代浏览器原生支持。FrankenPHP 内置了 Mercure Hub(仓库根目录的 docs/mercure.md 有完整说明,界面如下),因此 Laravel 应用无需额外部署 Hub 服务即可获得实时能力。
- 未使用 Octane 时:按 docs/mercure.md 在
Caddyfile中启用mercure指令并配置 JWT 密钥即可,Laravel 侧通过mercure_publish()函数、file_get_contents()请求或第三方库发布更新。 - 使用 Octane 时:在
config/octane.php中加入以下配置启用内置 Hub:
// config/octane.php // ... return [ // ... 'mercure' => [ 'anonymous' => true, 'publisher_jwt' => '!ChangeThisMercureHubJWTSecretKey!', 'subscriber_jwt' => '!ChangeThisMercureHubJWTSecretKey!', ], ];anonymous允许匿名订阅;publisher_jwt与subscriber_jwt是 Hub 签发与校验 JWT 的密钥,生产环境务必替换为高强度随机值。Mercure 支持的全部 Hub 配置指令都可以写进这个数组(例如subscriptions订阅 API、cors_origins跨域等)。
发布与订阅更新时,推荐使用 Laravel Mercure Broadcaster 库;不引入额外依赖时,也可以参照 docs/mercure.md 用纯 PHP(mercure_publish())与原生 JavaScript(EventSource)实现:客户端订阅/.well-known/mercure?topic=...端点,服务端发布带 JWT 授权的 POST 请求。
七、把 Octane 应用也打包成独立二进制
Octane 应用同样可以打包为独立二进制。步骤是:先按第三节完成 Octane 的安装配置,再按第四节完成打包;之后通过 Octane 以 Worker 模式启动 FrankenPHP:
PATH="$PWD:$PATH" frankenphp php-cli artisan octane:frankenphp[!CAUTION] 该命令要能工作,独立二进制必须命名为
frankenphp,并且要出现在PATH中(因此上面的命令把当前目录加入了PATH)——Octane 启动时需要在路径里找到一个名为frankenphp的程序。
这一步的原理可以追溯到 caddy/php-cli.go 的实现:php-cli会把当前二进制的路径作为argv[0]传入 PHP CLI SAPI,而 Octane 正是借助这一点找到"当前正在执行的服务器程序"来启动 Worker;docs/worker.md 也明确指出 Laravel Octane 就是 FrankenPHP Worker 模式在框架层的官方集成。
小结
从开发到生产再到分发,FrankenPHP 为 Laravel 提供了四档可选的运行形态:Docker 镜像一行命令即可起步;本地独立二进制配合Caddyfile适合常规部署;Laravel Octane 借助 Worker 模式让应用常驻内存、请求响应达到毫秒级;而嵌入特性则能把整个应用压缩进单个静态二进制,实现真正的"应用即文件"。配合内置的 Mercure Hub 与自动 HTTPS,Laravel 应用可以在不引入额外基础设施的前提下同时获得高性能与实时能力。更多底层机制可继续阅读 docs/config.md、docs/worker.md、docs/embed.md 与 docs/mercure.md。
【免费下载链接】frankenphp🧟 The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考