ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

FrankenPHP 配置完全指南:Caddyfile、php.ini 与环境变量的深度实战解析

FrankenPHP 配置完全指南:Caddyfile、php.ini 与环境变量的深度实战解析 FrankenPHP 配置完全指南Caddyfile、php.ini 与环境变量的深度实战解析【免费下载链接】frankenphp The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphpFrankenPHP 将 PHP 解释器直接嵌入 Caddy Web 服务器其全部能力——PHP 线程管理、Worker 模式、文件监控、PHP 运行时调优等——都通过 Caddyfile以及 php.ini、环境变量暴露给使用者。本文以官方配置文档 docs/cn/config.md 为主体结合仓库源码剖析每个指令的底层实现帮助你掌握从最小可运行配置到多 Worker、按路径匹配、线程自动重启等生产级配置的完整技能。配置体系总览FrankenPHP、Caddy 本身以及内置的 Mercure 和 Vulcain 模块都使用 Caddy 支持的配置格式 进行配置。最常见的格式是Caddyfile——一种简单、易读的文本格式。默认情况下FrankenPHP 会在当前目录查找Caddyfile也可以使用-c或--config选项指定自定义路径。此外PHP 自身可以通过标准的php.ini文件 配置。一个用于服务 PHP 应用的最小Caddyfile如下# 响应的主机名 localhost # 可选提供文件的目录否则默认为当前目录 #root public/ php_server不同安装方式的配置文件位置根据安装方法的不同FrankenPHP 与 PHP 解释器会在不同位置查找配置文件。Docker 镜像FrankenPHP/etc/frankenphp/Caddyfile主配置文件/etc/frankenphp/Caddyfile.d/*.caddyfile自动加载的附加配置文件注意仓库自带的 caddy/frankenphp/Caddyfile 正是随 Docker 镜像分发的这份高级配置其末尾正是import Caddyfile.d/*.caddyfile并且通过{$SERVER_NAME:localhost}、{$SERVER_ROOT:public/}、{$CADDY_GLOBAL_OPTIONS}、{$FRANKENPHP_CONFIG}等占位符实现了环境变量注入。PHPphp.ini/usr/local/etc/php/php.ini默认情况下不提供php.ini附加配置文件/usr/local/etc/php/conf.d/*.iniPHP 扩展/usr/local/lib/php/extensions/no-debug-zts-YYYYMMDD/官方建议从 PHP 项目提供的模板中复制一份FROM dunglas/frankenphp # 生产环境: RUN cp $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini # 或开发环境: RUN cp $PHP_INI_DIR/php.ini-development $PHP_INI_DIR/php.iniRPM 和 Debian 包FrankenPHP/etc/frankenphp/Caddyfile主配置文件/etc/frankenphp/Caddyfile.d/*.caddyfile自动加载的附加配置文件PHPphp.ini/etc/php-zts/php.ini默认情况下会提供带有生产预设的php.ini附加配置文件/etc/php-zts/conf.d/*.ini静态二进制文件FrankenPHP在当前工作目录查找CaddyfilePHPphp.ini优先查找执行frankenphp run或frankenphp php-server时所在目录其次查找/etc/frankenphp/php.ini附加配置文件/etc/frankenphp/php.d/*.iniPHP 扩展无法动态加载必须将它们打包进二进制文件本身需要自己复制 PHP 源码 提供的php.ini-production或php.ini-development之一Caddyfile 配置php_server 与 php 指令在站点块site block中可以使用php_server或php两个 HTTP 指令 来服务 PHP 应用。最小示例localhost { # 启用压缩可选 encode zstd br gzip # 在当前目录中执行 PHP 文件并提供资源服务 php_server }frankenphp 全局选项还可以通过frankenphp全局选项 显式配置 FrankenPHP{ frankenphp { num_threads num_threads # 设置要启动的 PHP 线程数量。默认可用 CPU 数量的 2 倍。 max_threads num_threads # 限制可以在运行时启动的额外 PHP 线程的数量。默认值num_threads。可以设置为 auto。 max_wait_time duration # 设置请求在超时之前可以等待的最大时间直到找到一个空闲的 PHP 线程。 默认禁用。 max_idle_time duration # 设置一个自动扩展的线程在被停用之前可以空闲的最长时间。默认5s。 max_requests num # (实验性) 设置一个 PHP 线程在重启前将处理的最大请求数这有助于缓解内存泄漏问题。适用于常规线程和 worker 线程。默认值0 (无限制)。 php_ini key value # 设置一个 php.ini 指令。可以多次使用以设置多个指令。 worker { file path # 设置工作脚本的路径。 num num # 设置要启动的 PHP 线程数量默认为可用 CPU 数量的 2 倍。 env key value # 设置一个额外的环境变量为给定的值。可以多次指定以设置多个环境变量。 watch path # 设置要监视文件更改的路径。可以为多个路径多次指定。 name name # 设置worker的名称用于日志和指标。默认值worker文件的绝对路径。 max_consecutive_failures num # 设置在工人被视为不健康之前的最大连续失败次数-1意味着工人将始终重新启动。默认值6。 } } } # ...这些指令的实际解析逻辑位于 caddy/app.go 的FrankenPHPApp.UnmarshalCaddyfile中其中有几点值得注意的实现细节num_threads、max_threads、max_requests均以ParseUint解析为非负整数max_threads还支持特殊值auto在源码中映射为-1表示不设上限max_wait_time、max_idle_time通过time.ParseDuration解析因此必须使用 Go 的时长格式如10s、30m解析结束后会做一致性校验若max_threads大于 0 且小于num_threads会直接报错要求max_threads必须大于等于num_threads配置会被翻译为 Caddy JSON 中的frankenphpapp 模块最终在Start()中通过frankenphp.WithNumThreads、frankenphp.WithMaxThreads、frankenphp.WithPhpIni、frankenphp.WithMaxWaitTime、frankenphp.WithMaxIdleTime、frankenphp.WithMaxRequests等选项驱动底层 PHP 引擎启动。worker选项还提供一行简短形式{ frankenphp { worker file num } } # ...在同一服务器上服务多个应用多 Worker如果一台服务器上托管多个应用可以分别定义各自的 workerapp.example.com { root /path/to/app/public php_server { root /path/to/app/public # 允许更好的缓存 worker index.php num } } other.example.com { root /path/to/other/public php_server { root /path/to/other/public worker index.php num } } # ...注意两点见 caddy/module.go 与 caddy/workerconfig.go定义在php_server块内的 worker其file路径可以相对于该站点根目录解析模块 Provision 时会拼接f.Root这类 worker 的名称总是以m#前缀开头见generateUniqueModuleWorkerName用于日志与指标区分同一站点块内不允许出现重复的 worker 文件名。php_server 与 php 指令的取舍php_server指令通常就是你需要的全部但如果你需要完全控制可以使用更低级的php指令。php指令将所有输入直接传递给 PHP而不是先检查请求是否对应一个 PHP 文件。关于try_files的更多细节见 性能页面。从源码看caddy/caddy.gophp与php_server被注册为不同的指令php直接注册为 handler 指令php_server则是parsePhpServer生成的快捷方式展开为一组 route见下文。php_server 的等价展开php_server指令完全等价于以下配置该展开逻辑在 caddy/module.go 的parsePhpServer中逐条实现其中重定向、重写、PHP 分发、静态文件服务四条 route 依次构建route { # 为目录请求添加尾斜杠 canonicalPath { file {path}/index.php not path */ } redir canonicalPath {path}/ 308 # 如果请求的文件不存在则尝试 index 文件 indexFiles file { try_files {path} {path}/index.php index.php split_path .php } rewrite indexFiles {http.matchers.file.relative} # FrankenPHP! phpFiles path *.php php phpFiles file_server }php_server 与 php 指令的选项php_server [matcher] { root directory # 将根文件夹设置为站点。默认值root 指令。 split_path delim... # 设置用于将 URI 分割成两部分的子字符串。第一个匹配的子字符串将用来将 路径信息 与路径分开。第一部分后缀为匹配的子字符串并将被视为实际资源CGI 脚本名称。第二部分将被设置为脚本使用的 PATH_INFO。默认值.php。 resolve_root_symlink false # 禁用通过评估符号链接如果存在将 root 目录解析为其实际值默认启用。 env key value # 设置一个额外的环境变量为给定的值。可以多次指定以设置多个环境变量。 file_server off # 禁用内置的 file_server 指令。 worker { # 为此服务器创建特定的worker。可以多次指定以创建多个workers。 file path # 设置工作脚本的路径可以相对于 php_server 根目录 num num # 设置要启动的 PHP 线程数默认为可用 CPU 数量的 2 倍 name name # 为worker设置名称用于日志和指标。默认值worker文件的绝对路径。定义在 php_server 块中时始终以 m# 开头。 watch path # 设置要监视文件更改的路径。可以为多个路径多次指定。 env key value # 设置一个额外的环境变量为给定值。可以多次指定以设置多个环境变量。此工作进程的环境变量也从 php_server 父进程继承但可以在此处覆盖。 match path # 将worker匹配到路径模式。覆盖 try_files并且只能在 php_server 指令中使用。 } worker other_file num # 也可以像在全局 frankenphp 块中那样使用简短形式。 }补充几个源码层面的细节split_path默认值为.phpcaddy/module.go 中f.SplitPath []string{.php}并经由frankenphp.WithRequestSplitPath注入请求处理链决定 PATH_INFO 如何切分request_body_timeout也是该指令的隐含选项未指定时默认 60 秒常量defaultRequestBodyTimeout见 caddy/caddy.go其设计对齐 nginx 的client_body_timeout设置为0可禁用。它作用于请求体读取的空闲超时慢速slow POST客户端会被断开而持续稳定上传的大文件不受影响resolve_root_symlink默认开启ResolveRootSymlink new(true)模块 Provision 时会用filepath.EvalSymlinks解析 root 的真实路径并同步解析 worker 文件路径中的符号链接env的继承定义在php_server块内的 worker 会通过workerConfig.inheritEnv继承父级env且已存在的键不会被覆盖。监控文件变化watch由于 worker 只会启动一次应用并将其常驻内存PHP 文件的任何修改都不会立即生效。可以通过watch指令让 worker 在文件变更时自动重启——这对开发环境非常有用{ frankenphp { worker { file /path/to/app/public/worker.php watch } } }该功能常与热重载搭配使用热重载基于 Mercure 推送页面自动刷新而watch负责重启 worker 进程两者互补。如果没有指定watch目录将回退到默认模式./**/*.{env,php,twig,yaml,yml}——即监控 FrankenPHP 进程启动目录及其所有子目录中的.env、.php、.twig、.yaml、.yml文件。这个默认模式定义在 caddy/caddy.go 的defaultWatchPattern常量中并在 caddy/workerconfig.go 的unmarshalWorker中被填充。你也可以通过 shell 文件名模式 指定一个或多个目录{ frankenphp { worker { file /path/to/app/public/worker.php watch /path/to/app # 监视 /path/to/app 所有子目录中的所有文件 watch /path/to/app/*.php # 监视位于/path/to/app中的以.php结尾的文件 watch /path/to/app/**/*.php # 监视 /path/to/app 及子目录中的 PHP 文件 watch /path/to/app/**/*.{php,twig} # 在/path/to/app及其子目录中监视PHP和Twig文件 } } }使用要点**模式表示递归监视目录也可以是相对的相对于 FrankenPHP 进程启动的位置如果定义了多个 worker任意文件变更会重启所有 worker小心监视运行时才创建的文件如日志它们可能引发不必要的 worker 重启。文件监视器基于 e-dant/watcher 实现。将 worker 匹配到一条路径match传统 PHP 应用中脚本总是放在公共目录里worker 脚本也不例外。如果想把 worker 脚本放到公共目录之外可以使用match指令。match是try_files的一种优化替代方案仅可在php_server和php内部使用。下面的示例公共目录中存在的文件始终直接提供其余请求按路径模式转发给匹配的 worker{ frankenphp { php_server { worker { file /path/to/worker.php # 文件可以在公共路径之外 match /api/* # 所有以 /api/ 开头的请求将由此 worker 处理 } } } }实现层面caddy/module.go 的prependWorkerRoutes带match的 worker 会为匹配路径预先插入路由——先检查文件是否存在非.php文件由file_server直接服务再按路径模式把请求交给 PHP handlercaddy/workerconfig.go 的matchesPath中还针对静态 root 做了预计算相对路径的快速匹配优化。在处理一定数量请求后重启线程实验性FrankenPHP 可以在 PHP 线程处理完给定数量的请求后自动将其完全重启清除全部内存与状态重启期间其他线程继续服务请求。如果发现内存随时间增长理想方案是向导致泄漏的扩展或库的维护者报告问题但当修复依赖你无法控制的第三方时max_requests提供了一个务实且有望临时的生产环境缓解手段{ frankenphp { max_requests 500 } }环境变量注入无需修改Caddyfile就可以通过以下环境变量注入 Caddy 指令SERVER_NAME更改监听的地址提供的主机名也会用于生成的 TLS 证书SERVER_ROOT更改网站的根目录默认为public/CADDY_GLOBAL_OPTIONS注入全局选项FRANKENPHP_CONFIG在frankenphp指令下注入配置。这些占位符正是 caddy/frankenphp/Caddyfile 中{$CADDY_GLOBAL_OPTIONS}、{$FRANKENPHP_CONFIG}、{$SERVER_NAME:localhost}、{$SERVER_ROOT:public/}的取值来源其默认值也写在此文件中。与 FPM 和 CLI SAPI 一样环境变量默认暴露在$_SERVER超全局中。特别地variables_orderPHP 指令中的S值始终等价于ES——无论E在该指令的其他位置如何。PHP 配置加载附加 php.ini 文件使用PHP_INI_SCAN_DIR环境变量可以加载附加的 PHP 配置文件。设置后PHP 会加载给定目录中所有带.ini扩展名的文件。在 Caddyfile 中使用 php_ini 指令你也可以通过php_ini指令直接修改 PHP 配置{ frankenphp { php_ini memory_limit 256M # 或者 php_ini { memory_limit 256M max_execution_time 15 } } }两种写法都支持单行php_ini key value可重复使用块写法可一次设置多条。解析器caddy/app.go会严格校验格式必须是php_ini key value超出两个参数会报错。禁用 HTTPS默认情况下 FrankenPHP 会自动为所有主机名包括localhost启用 HTTPS。想禁用例如开发环境可以把SERVER_NAME环境变量设置为http://或:80SERVER_NAMEhttp://localhost或者使用 Caddy 文档 中描述的其他所有方法。如果想对127.0.0.1IP 地址而非localhost主机名使用 HTTPS请阅读已知问题部分。全双工HTTP/1使用 HTTP/1.x 时可能希望启用全双工模式以便在读取完整请求体之前就允许写入响应例如Mercure、WebSocket、Server-Sent Events 等场景。这是一个可选配置需添加到 Caddyfile 的全局选项中{ servers { enable_full_duplex } }[!CAUTION]启用此选项可能导致不支持全双工的旧 HTTP/1.x 客户端死锁。也可以通过CADDY_GLOBAL_OPTIONS环境变量配置CADDY_GLOBAL_OPTIONSservers { enable_full_duplex }更多信息参见 Caddy 文档。启用调试模式使用 Docker 镜像时将CADDY_GLOBAL_OPTIONS环境变量设为debug即可启用调试模式docker run -v $PWD:/app/public \ -e CADDY_GLOBAL_OPTIONSdebug \ -p 80:80 -p 443:443 -p 443:443/udp \ dunglas/frankenphpShell 补全FrankenPHP 内置对 Bash、Zsh、Fish 和 PowerShell 的 shell 补全支持覆盖所有命令包括php-server、php-cli、extension-init等自定义命令及其标志。Bash当前会话加载source (frankenphp completion bash)永久加载——Linuxfrankenphp completion bash /usr/share/bash-completion/completions/frankenphpmacOSfrankenphp completion bash $(brew --prefix)/share/bash-completion/completions/frankenphpZsh如果环境中尚未启用 shell 补全先执行一次echo autoload -U compinit; compinit ~/.zshrc再为每个会话加载补全执行一次frankenphp completion zsh ${fpath[1]}/_frankenphp需要启动一个新的 shell 会话才能生效。Fish当前会话加载frankenphp completion fish | source永久加载执行一次frankenphp completion fish ~/.config/fish/completions/frankenphp.fishPowerShell当前会话加载frankenphp completion powershell | Out-String | Invoke-Expression永久加载执行一次frankenphp completion powershell | Out-File -FilePath (Join-Path (Split-Path $PROFILE) frankenphp.ps1) Add-Content -Path $PROFILE -Value . (Join-Path (Split-Path $PROFILE) frankenphp.ps1)需要启动一个新的 shell 会话才能生效。实战建议与快速参考从镜像开始Docker 用户可直接使用仓库自带的 caddy/frankenphp/Caddyfile 作为基准它已内置压缩encode zstd br gzip、public/根目录、Mercure/Vulcain 模块开关和环境变量注入并默认import Caddyfile.d/*.caddyfile方便扩展生产 vs 开发Docker 内用php.ini-production还是php.ini-development按环境选择静态二进制则需自己放置php.iniWorker 模式先全局worker或站点内worker index.php启用常驻内存再配合watch开发与match路径分发落地内存问题兜底第三方扩展泄漏时用max_requests定期重启线程同时结合max_idle_time默认 5s控制自动扩缩线程的空闲回收排查问题CADDY_GLOBAL_OPTIONSdebug一键开启调试日志num_threads/max_threads明确线程基数与扩容上限。更完整的源码级实现可继续阅读 caddy/app.go全局指令解析与线程启动、caddy/module.gophp_server/php指令与请求分发、caddy/workerconfig.goworker 配置与路径匹配、caddy/hotreload.go热重载以及 caddy/php-server.gofrankenphp php-server命令的默认路由构建结合 caddy 目录测试 与 caddy/config_test.go 观察各指令的解析与校验行为。【免费下载链接】frankenphp The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表