laravel在kubernetes上无法运行的三大主因是环境变量错误、健康检查配置不当和storage权限问题:db_host须用service dns名而非localhost;livenessprobe应调用轻量级/healthz路由;dockerfile需清空storage与cache再copy。

Laravel 在 Kubernetes 上跑不起来,90% 是环境变量写错、健康检查没配、storage 权限乱了这三件事导致的。
DB_HOST 不能写 localhost 或 127.0.0.1
这是最常踩的坑:Kubernetes Pod 内没有本地 MySQL,DB_HOST: localhost 会导致 PDO 连接拒绝,报错 SQLSTATE[HY000] [2002] Connection refused。
- 必须用 MySQL Service 的 DNS 名,比如
mysql-service(对应 YAML 中metadata.name) - 别用 Pod IP 或 ClusterIP——Service 名会被 K8s CoreDNS 自动解析成当前可用的后端 Pod IP
- 如果用了 Helm 部署 MySQL(如 bitnami/mysql),默认 Service 名通常是
mysql,不是mysql-primary或mysql-0
livenessProbe 必须调用自定义 /healthz 路由
直接用 readinessProbe 去请求 / 或 /api/health 很危险:首页加载慢、DB 临时抖动,就会把 Pod 反复踢出 Endpoints,流量中断。
- 在 Laravel 中加一个轻量路由:
Route::get('/healthz', fn() => response()->json(['status' => 'ok'], 200)); - Deployment 中配置:
livenessProbe.httpGet.path: /healthz,initialDelaySeconds: 30(Laravel 启动要加载 config、缓存、服务提供者) - 避免用
exec检查php-fpm -t——容器内 PHP-FPM 进程活着,不代表 Laravel 应用能响应 HTTP 请求
Dockerfile 里必须清空 storage/ 和 bootstrap/cache/ 再 COPY
构建镜像时如果保留宿主机的 storage/framework/cache/data 或 bootstrap/cache/config.php,运行时会因 UID/GID 不一致(比如 Alpine 的 www-data UID=82,Debian 是 33)导致 chmod 失败、opcache 加载异常,甚至 php-fpm 拒绝启动。
- 在
COPY . /var/www/html前加一句:RUN rm -rf storage/* bootstrap/cache/* - 不要依赖
chown -R www-data:www-data——initContainer 以 root 启动,但容器 runtime 可能限制 CAP_CHOWN,且不同基础镜像 UID 不统一 - 运行时用
emptyDir挂载storage/logs和storage/app,但storage/framework必须是容器内可写路径(不能只读挂载)
APP_ENV=production 不只是性能开关
设错 APP_ENV 会引发连锁故障:APP_ENV=local 导致 config:cache 生成的文件含调试信息,上线后报 Class 'App\Http\Controllers\Controller' not found;APP_ENV=staging 未定义则 fallback 到 production,但部分包行为不一致。
- Deployment 的
env字段中必须显式声明:- name: APP_ENV value: production - 敏感值如
APP_KEY一定要走Secret,别塞进env.value——YAML 泄露 = 密钥裸奔 - Ingress 配置需适配 Laravel 路由重写:Nginx Ingress 要加
nginx.ingress.kubernetes.io/rewrite-target: /,否则前端路由或 asset 加载 404
真正卡住人的从来不是“怎么部署”,而是 PHP-FPM 进程假死却不重启、日志写满后轮转失败、或者 Secret 挂载后权限被 initContainer 错误覆盖——这些细节不会报错,只会让请求缓慢超时或偶发 502。











