news 2026/9/15 22:34:39

FrankenPHP 运行 Laravel 全攻略:Docker 部署、Caddyfile 配置、Octane 加速与独立二进制打包

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FrankenPHP 运行 Laravel 全攻略:Docker 部署、Caddyfile 配置、Octane 加速与独立二进制打包

FrankenPHP 运行 Laravel 全攻略:Docker 部署、Caddyfile 配置、Octane 加速与独立二进制打包

【免费下载链接】frankenphp🧟 The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp

本篇技术指南完整讲解如何在 FrankenPHP(The modern PHP app server,内置 PHP 解释器的 Caddy Web 服务器)上运行 Laravel 应用的四种主流方案:Docker 镜像一键部署、本地二进制 + Caddyfile 配置、Laravel Octane 常驻内存加速,以及将整个 Laravel 应用打包为无依赖的独立静态二进制。读完本文,你将掌握每种方案的完整配置与命令、octane:frankenphp的全部参数,并能结合仓库源码理解php-cliphp-server、worker 模式与嵌入(embed)特性的底层原理。

为什么选择 FrankenPHP 承载 Laravel

FrankenPHP 将 PHP 解释器、Caddy Web 服务器与 PHP 应用融合为单一进程,天然具备生产级 HTTP 服务器能力(自动 HTTPS、HTTP/2、HTTP/3、压缩等),并可通过 worker 模式让 PHP 应用常驻内存、大幅削减每次请求的引导开销。对于 Laravel 开发者而言,官方 Docker 镜像与独立二进制两种分发形态,分别覆盖了"快速开发"与"轻量交付"两个典型场景。

方式一:使用官方 Docker 镜像运行 Laravel

官方 Docker 镜像(Dockerfile)已内置 FrankenPHP 二进制、默认的 Caddyfile 配置与 PHP 环境,工作目录固定为/app。因此,把 Laravel 项目挂载到镜像的/app目录即可直接对外提供服务:

docker run -p 80:80 -p 443:443 -p 443:443/udp -v $PWD:/app dunglas/frankenphp

从 Laravel 应用的主目录执行该命令即可。参数说明:

  • -p 80:80-p 443:443:分别暴露 HTTP 与 HTTPS 端口;
  • -p 443:443/udp:暴露 HTTP/3(基于 QUIC/UDP)端口,对应 Dockerfile 中的EXPOSE 80EXPOSE 443EXPOSE 443/udp
  • -v $PWD:/app:将当前目录(你的 Laravel 项目)挂载为镜像的 Web 根目录。

镜像默认的入口会以frankenphp run启动,并加载/etc/frankenphp/Caddyfile(该文件由 caddy/frankenphp/Caddyfile 生成)。仓库提供的默认站点配置与本文推荐的 Laravel 配置高度一致——站点根目录为public/、开启zstd br gzip压缩、使用php_server指令执行 PHP 文件。此外,镜像还提供了FRANKENPHP_CONFIG环境变量用于注入额外配置,例如开启 worker 模式:

docker run \ -e FRANKENPHP_CONFIG="worker /app/public/index.php" \ -v $PWD:/app \ -p 80:80 -p 443:443 -p 443:443/udp \ dunglas/frankenphp

该变量会被插入到默认 Caddyfile 的frankenphp { ... }全局块中(见 caddy/frankenphp/Caddyfile),worker 模式的完整说明见 docs/worker.md。

方式二:本地安装与 Caddyfile 配置

如果你更倾向于在本机直接运行,可以下载与操作系统对应的 FrankenPHP 独立二进制(参考根目录 README.md 的 standalone binary 章节),然后在 Laravel 项目根目录创建一个名为Caddyfile的文件:

{ frankenphp } # 你的服务器域名 localhost { # 将 Web 根目录设置为 public/ root public/ # 启用压缩(可选) encode zstd br gzip # 从 public/ 目录执行 PHP 文件并托管静态资源 php_server { try_files {path} index.php } }

逐段解读:

  • 全局块{ frankenphp }:启用 FrankenPHP 的 PHP 处理模块;
  • localhost站点块:这里以本地开发域名为例,生产环境请替换为你的真实域名(指定域名后 FrankenPHP 会自动签发并续期 Let's Encrypt 证书,启用 HTTPS/HTTP/2/HTTP/3);
  • root public/:Laravel 的入口目录是public/,必须将根目录指向它,否则框架入口无法被正确解析;
  • encode zstd br gzip:依次启用 Zstandard、Brotli、Gzip 三种压缩编码,由 Caddy 的encode模块按客户端协商结果选择;
  • php_server+try_files {path} index.php:这是 Laravel 前端控制器模式的标准写法——先尝试按请求路径匹配静态文件,找不到时回退到index.php,由框架路由接管。

配置完成后,在 Laravel 项目根目录启动:

frankenphp run

frankenphp run会读取当前目录(或通过--config指定的)Caddyfile 并启动服务器。需要更灵活的场景时,还可以使用frankenphp php-server命令直接以零配置方式起一个 PHP 服务器(详见下文"独立二进制"一节)。

Laravel Octane:让应用常驻内存

Laravel Octane 是 Laravel 官方的高性能应用服务器方案,它把应用"预热"一次并常驻内存,使请求处理吞吐大幅提升,这与 FrankenPHP 的 worker 模式天然契合——Octane 的 FrankenPHP 驱动正是建立在 worker 模式之上的。

安装与启动

先用 Composer 安装 Octane:

composer require laravel/octane

然后执行octane:install,它会将 Octane 的配置文件安装到你的应用中,--server=frankenphp指定使用 FrankenPHP 作为驱动:

php artisan octane:install --server=frankenphp

启动 Octane 服务器:

php artisan octane:frankenphp

octane:frankenphp 的可用选项

选项含义默认值
--host服务器绑定的 IP 地址127.0.0.1
--port服务器监听的端口8000
--admin-port管理服务器(Caddy Admin API)端口2019
--workers用于处理请求的 worker 数量auto
--max-requests每处理多少请求后重启一次 worker500
--caddyfileFrankenPHPCaddyfile的路径Octane 内置的 Caddyfile 模板(stub)
--https启用 HTTPS、HTTP/2 与 HTTP/3,并自动生成和续期证书关闭
--http-redirect将 HTTP 请求重定向到 HTTPS(仅在传入--https时生效)关闭
--watch应用文件发生变化时自动重载服务器关闭
--poll监听文件时使用文件系统轮询(适用于网络文件系统上的文件监听)关闭
--log-level按指定级别(或更高级别)输出日志,使用 Caddy 原生 logger

[!TIP] 如需输出结构化 JSON 日志(便于对接日志分析平台),请显式传入--log-level选项。

从实现层面看,--workers--max-requests分别对应 FrankenPHP worker 模式的 worker 数量与按请求数重启策略(docs/worker.md 中介绍了MAX_REQUESTS环境变量与max_consecutive_failures等配置);--admin-port暴露的正是 Caddy 管理 API,可通过curl -X POST http://localhost:2019/frankenphp/workers/restart优雅重启全部 worker。--watch底层由仓库的 watcher 模块与hot-reload特性支撑(见 docs/hot-reload.md)。

将 Laravel 应用打包为独立二进制

借助 FrankenPHP 的应用嵌入(embed)特性,可以把"Laravel 应用源码 + PHP 解释器 + Caddy 服务器"压缩进一个可执行文件。交付时不再需要安装 PHP、Composer 或任何运行时依赖,非常适合分发给客户、部署到内网服务器等场景。以下步骤以 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,否则应用依赖与环境配置不会被打进二进制。

该 Dockerfile 基于仓库提供的 static-builder-gnu.Dockerfile 静态构建镜像(glibc 变体),EMBED=dist/app/告诉构建脚本将dist/app/(即你的应用)嵌入最终二进制。

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-tmp

当前目录下得到的frankenphp就是自包含的可执行文件。

4. 初始化应用(php-cli)

嵌入后的二进制内置了完整的 PHP CLI 能力——caddy/php-cli.go 注册了php-cli子命令,其底层调用frankenphp.ExecuteScriptCLI()(见 cli.go)以 PHP CLI SAPI 方式执行脚本。因此可以直接在二进制内运行 Artisan 命令:

frankenphp php-cli artisan optimize
frankenphp php-cli artisan migrate
frankenphp php-cli artisan key:generate

依次完成:生成/填充各类缓存、执行数据库迁移(如有)、生成应用密钥。这三步都属于"写操作",在嵌入只读二进制的场景下建议在发布前完成。

5. 启动服务器(php-server)

frankenphp php-server

php-server是 caddy/php-server.go 注册的生产级 PHP 服务器命令,常用选项包括:--domain(指定域名自动启用 HTTPS)、--root(站点根目录)、--listen(监听地址)、--worker(worker 脚本,可带,数量后缀)、--watch(文件变更自动重载)、--access-log--mercure(启用内置 Mercure hub)等。当检测到应用嵌入路径且根目录存在自定义Caddyfile时,它会自动加载该配置(见 caddy/php-server.go),因此你也可以在应用根目录放一份自定义 Caddyfile 来覆盖默认行为。

至此,你的 Laravel 应用已作为一个独立二进制运行起来。

嵌入式应用的注意事项

更改存储路径

Laravel 默认把上传文件、缓存、日志等写入应用目录下的storage/。这对嵌入式应用并不合适——因为每次新版本二进制运行时,应用会被解压到不同的临时目录,storage/数据无法持久。

解决办法有两种:

  1. 设置环境变量LARAVEL_STORAGE_PATH(例如写入你的.env文件),指定一个临时目录之外的固定路径;
  2. 或调用Illuminate\Foundation\Application::useStoragePath()方法,在应用引导阶段把存储路径指向外部目录。

用独立二进制运行 Octane

独立二进制同样可以运行 Laravel Octane!按上文"Laravel Octane"一节安装好 Octane,并按"独立二进制"一节完成打包后,以如下方式启动(worker 模式):

PATH="$PWD:$PATH" frankenphp php-cli artisan octane:frankenphp

[!CAUTION] 该命令要生效,独立二进制必须命名为frankenphp并出现在PATH中,因为 Octane 需要调用一个名为frankenphp的程序。PATH="$PWD:$PATH"正是把当前目录(二进制所在处)临时加入PATH

进阶:为 Laravel/Octane 启用 Mercure 实时推送

FrankenPHP 内置了 Mercure hub,可向浏览器实时推送事件,是 WebSocket 的轻量替代方案(Laravel 官方文档的 Mercure 支持 章节也收录了此用法)。

若未使用 Octane,直接在 Caddyfile 中按 docs/mercure.md 的示例启用mercure指令即可。若使用 Octane,则在config/octane.php中添加如下配置:

// config/octane.php // ... return [ // ... 'mercure' => [ 'anonymous' => true, 'publisher_jwt' => '!ChangeThisMercureHubJWTSecretKey!', 'subscriber_jwt' => '!ChangeThisMercureHubJWTSecretKey!', ], ];

该数组支持 Mercure hub 的全部指令(anonymous表示允许匿名订阅者;publisher_jwtsubscriber_jwt为发布者/订阅者 JWT 签名密钥,生产环境务必更换)。发布更新可借助 FrankenPHP 提供的mercure_publish()函数(签名见 docs/mercure.md),或使用社区维护的 Laravel Mercure Broadcaster 库与原生EventSource订阅;纯 PHP/JavaScript 的完整示例同样在 docs/mercure.md 中。

小结

围绕 Laravel 与 FrankenPHP 的组合,本文覆盖了四条落地路径:

  1. Docker:挂载/app目录即可运行,适合快速开发与 CI 环境;
  2. 本地安装:独立二进制 + Caddyfile(root public/encodephp_server),适合本机调试;
  3. Laravel Octaneoctane:install --server=frankenphp+octane:frankenphp,借助 worker 模式实现常驻内存,参数覆盖 host、port、workers、max-requests、HTTPS、watch 等;
  4. 独立二进制:通过static-build.Dockerfile将应用嵌入静态二进制,配合php-cli执行 Artisan、php-server启动服务,实现零运行时依赖的分发。

无论选择哪种方式,仓库中的 docs/embed.md、docs/worker.md、docs/mercure.md 以及 caddy/frankenphp/Caddyfile 默认配置,都是继续深入 FrankenPHP 能力边界的绝佳入口。

【免费下载链接】frankenphp🧟 The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 22:34:10

Docker部署SRS流媒体服务器:从RTMP到WebRTC实战指南

去年给公司做内部培训直播,我一开始用的是Nginx-RTMP,推流倒是挺稳,但后来要接WebRTC低延迟播放,Nginx那边弄了半天还是不顺,最后换成SRS才彻底解决问题。如果你也正琢磨怎么用Docker快速部署一套SRS,把实时…

作者头像 李华
网站建设 2026/9/15 22:31:37

SpringBoot+Vue+微信小程序构建民宿预约系统实战

1. 项目背景与核心价值"117民宿预约管理系统"是一个典型的OMO(Online-Merge-Offline)场景解决方案。作为从业十余年的全栈开发者,我见证过太多民宿业主用Excel甚至纸质本子管理房态的混乱场景。这套系统通过SpringBootVue微信小程序…

作者头像 李华
网站建设 2026/9/15 22:28:17

VS Code + STM32嵌入式开发环境搭建与AI编程实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 22:27:13

API安全与AI模型投毒攻击的防御实践

1. 项目概述:当API安全遇上AI模型投毒去年某次内部安全审计中,我发现一个诡异现象:企业API网关日志里出现了大量看似正常的模型推理请求,但返回结果却逐渐偏离预期。经过72小时追踪,最终确认这是一起精心设计的模型投毒…

作者头像 李华