frankenphp 容器默认运行 caddy+php 服务而非 shell,直接执行 php artisan 会因容器立即退出而失败;正确方式是 docker run -it --rm -v $pwd:/app dunglas/frankenphp sh 进入交互式 shell 后执行命令。

容器内执行 php artisan 命令必须进 shell,不能直接挂载后就运行
FrankenPHP 官方镜像(如 dunglas/frankenphp)默认启动的是 Caddy + PHP 服务进程,不是交互式 shell。直接在 docker run 命令末尾加 php artisan migrate 会失败——容器启动后立刻退出,命令根本没机会执行。
正确做法是先让容器以交互模式跑起来,再进去操作:
- 用
docker run -it --rm -v $PWD:/app dunglas/frankenphp sh启动一个临时 shell - 进容器后切到项目根目录:
cd /app - 再执行命令,比如
php artisan migrate或php artisan key:generate
注意:该镜像的 PHP 已预装常用扩展(opcache、pdo_sqlite、mbstring 等),但没装 pdo_mysql 或 pgsql —— 如果要用 MySQL/PostgreSQL,得自己基于该镜像构建新镜像并安装对应扩展。
php artisan octane:start 在容器里会卡住,别这么干
FrankenPHP 镜像本身已内置 Caddy 和 PHP 运行时,php artisan octane:start --server=frankenphp 是给本地开发或非容器环境用的。在容器里再跑一遍 Octane,等于让 FrankenPHP 套娃启动 FrankenPHP,结果就是进程冲突、端口占用、Caddy 无法绑定 :80。
容器场景下,Octane 的角色已被镜像接管,你只需:
- 确保已执行过
php artisan octane:install --server=frankenphp(在宿主机或构建阶段做) - 确认
vendor/bin/frankenphp-worker.php存在且可执行(chmod +x) - 容器启动时,它会自动加载 worker 模式,不需要手动调
octane:start
如果看到 Address already in use 或 Failed to bind to :80,八成是误启了两次服务。
数据库迁移失败?检查 DB_HOST 和 socket 路径
容器内执行 php artisan migrate 报 Connection refused,大概率是数据库连接配置没对上。FrankenPHP 镜像不自带数据库,你得额外起一个 mysql 或 postgres 容器,并在 Laravel 的 .env 里显式指定:
-
DB_HOST=db(对应 Docker Compose 中的服务名,不是localhost) -
DB_PORT=3306(MySQL)或5432(PostgreSQL) - 别用
unix_socket,容器间通信走 TCP,DB_SOCKET必须留空或删掉
如果用 SQLite,路径要写绝对路径,例如 DB_DATABASE=/app/database/database.sqlite,并确保 /app/database/ 目录存在且可写(chmod -R 775 database/)。
想自动化执行 migrate?用 entrypoint 脚本而不是 CMD
硬编码 php artisan migrate 到 Dockerfile 的 CMD 里很危险——每次重启容器都会重跑迁移,可能破坏数据。更稳妥的方式是写一个 entrypoint.sh:
#!/bin/sh if [ "$1" = "php" ] && [ "$2" = "artisan" ]; then exec "$@" elif [ "$1" = "migrate" ]; then php artisan migrate --force exec php artisan octane:start --server=frankenphp else exec "$@" fi
然后在 docker run 里用:docker run ... dunglas/frankenphp migrate。这样既可控,又不会污染主服务流程。
真正容易被忽略的点是:FrankenPHP 容器默认不监听 STDIN,如果你在脚本里用了 read 或等待交互输入,它会直接 hang 住——所有初始化逻辑必须是非阻塞、无交互的。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











