frankenphp容器内修改php.ini重启后失效,因镜像启动时自动覆盖该文件;应挂载自定义ini至conf.d/或用caddyfile的php_ini指令配置。

FrankenPHP 容器里改了 php.ini,重启容器就失效——这是默认镜像设计导致的,不是你操作错了。
为什么容器内修改 php.ini 会丢失
官方镜像 dunglas/frankenphp 启动时会自动覆盖 /usr/local/etc/php/php.ini:它优先读取环境变量 PHP_INI_DIR 下的 php.ini-production 或 php.ini-development,并硬链接/复制到运行时路径。你手动编辑的文件在容器重建后会被重置。
- 镜像启动逻辑里有类似
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"的步骤 -
php.ini不在 Docker volume 挂载路径中,默认属于只读层 - 即使用
docker exec -it进去改,下次docker run或docker-compose up就恢复原样
正确持久化 php.ini 的三种方式
核心原则:让自定义配置在容器启动早期生效,且不被镜像初始化脚本覆盖。
-
推荐:挂载自定义 php.ini 到
/usr/local/etc/php/conf.d/99-custom.iniFrankenPHP(及底层 PHP)会按字母序加载conf.d/下所有.ini文件,99-前缀确保它最后加载、能覆盖前面的设置。只需在docker-compose.yaml中加:volumes: - ./config/php/99-custom.ini:/usr/local/etc/php/conf.d/99-custom.ini:ro
-
替代方案:用
php_ini指令在 Caddyfile 中设置 在Caddyfile的frankenphp { }块内直接写:frankenphp { php_ini memory_limit 512M php_ini opcache.enable 1 php_ini date.timezone "Asia/Shanghai" }这些指令会在 PHP 启动时注入,优先级高于php.ini,但仅支持部分 ini 指令(如不能设extension=) -
不推荐:构建自定义镜像覆盖 php.ini
虽然可行(
COPY my-php.ini /usr/local/etc/php/php.ini),但失去上游镜像更新能力,每次 FrankenPHP 升级都要重新构建,维护成本高
验证 php.ini 是否真正生效
别只信 phpinfo() 页面显示的 “Loaded Configuration File” 路径——它可能仍显示 /usr/local/etc/php/php.ini,但实际生效的是 conf.d/ 下的合并结果。
- 执行
docker exec <container> php -i | grep "memory_limit\|opcache"</container>,看输出是否为你设的值 - 检查 OPcache 是否启用:
docker exec <container> php -r "var_dump(opcache_get_status()['opcache_enabled']);"</container> - 如果用了
php_ini指令,注意它不改变phpinfo()中的配置文件路径,只影响运行时值
最易忽略的一点:FrankenPHP 的 php_ini 指令不支持动态扩展加载(比如 extension=redis.so),这类必须走 conf.d/ 挂载或构建镜像;而内存、时区、OPcache 开关等运行时参数,用 Caddyfile 配置反而更轻量、更可追踪。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











