php项目gitlab ci最稳妥起点是用php:8.2-cli镜像,需启用pdo_mysql、mbstring、xml扩展,禁用opcache;composer加--no-interaction和--prefer-dist;phpunit测试需对齐bootstrap路径、用services配mysql服务名作db_host;部署用rsync时注意源目标路径斜杠及权限;.env变量须拆解为受保护的ci变量生成。

GitLab CI 里怎么写 PHP 项目的 .gitlab-ci.yml
PHP 项目走 GitLab CI 最稳妥的起点是用官方 php:8.2-cli 镜像,但直接跑会卡在缺少扩展或 Composer 权限问题上。关键不是“装全所有扩展”,而是按实际需要精简启用:
-
pdo_mysql、mbstring、xml这三个几乎必开;opcache在测试阶段建议关掉,避免缓存干扰单元测试结果 - 用
composer install --no-dev --optimize-autoloader构建生产包,但 CI 流水线里测试阶段必须保留--no-interaction和--prefer-dist,否则可能卡在交互式提示或源码拉取超时 - 别在
before_script里反复apt-get update—— 每次都会触发新层,改用预构建的自定义镜像(比如基于php:8.2-cli装好git、curl、rsync的轻量镜像)更稳
如何让 PHPUnit 测试不因环境差异失败
本地能过、CI 报 Class 'Tests\TestCase' not found 或数据库连接超时,八成是自动加载或配置没对齐。核心矛盾不在代码,而在 phpunit.xml 和 CI 环境的耦合点:
-
phpunit.xml里的bootstrap路径要写相对项目根目录的路径(如tests/bootstrap.php),不能依赖vendor/autoload.php默认位置;CI 容器内工作目录未必是项目根 - 数据库测试别硬编码
localhost—— GitLab CI 用services启mysql:8.0时,host 是服务名mysql,得通过DB_HOST=mysql注入环境变量,再在phpunit.xml里用${DB_HOST}引用 - 如果用了 Laravel,
APP_ENV=testing必须显式设置,否则config/database.php可能读不到sqlite内存驱动配置
部署到线上服务器时 rsync 总丢文件或权限错
用 rsync -avz --delete 推代码看似简单,实际常因用户权限、SELinux 或目标目录结构导致失败。重点不是参数多,而是控制权归属:
- CI runner 所用用户(如
gitlab-runner)必须对目标服务器有免密ssh权限,且该用户在远程机器上有写入/var/www/myapp的权限 —— 别指望用root,多数运维禁用 root ssh -
--delete很危险:如果rsync源路径末尾多了/(比如写成dist/而非dist),它会清空目标整个目录;CI 脚本里统一用rsync -avz --delete dist/ user@host:/var/www/myapp/(源带斜杠,目标也带) - PHP 文件执行权限一般不需要
+x,但storage和bootstrap/cache目录必须可写,上线后加一句ssh user@host 'chown -R www-data:www-data /var/www/myapp/storage /var/www/myapp/bootstrap/cache'
为什么 .env 文件不能进 Git,又不能靠 CI 人工传
.env 进 Git 是安全红线,但每次上线手动 scp 一份过去,迟早出错。GitLab CI 的 variables 只能存字符串,存不了带换行的完整文件,所以得拆解处理:
- 把
.env拆成若干个 CI 变量:DB_DATABASE、APP_KEY、MAIL_HOST…… 在.gitlab-ci.yml的variables块里定义,标记为protected且masked - 在 deploy job 里用
echo "DB_DATABASE=${DB_DATABASE}" > .env逐行生成,注意APP_KEY这类含特殊字符的值要用单引号包裹,避免 shell 解析错误 - 别忘了
APP_KEY必须提前用php artisan key:generate --show生成并存为变量,否则 Laravel 启动直接报错
真正麻烦的从来不是写完流水线,而是每次上线前确认 storage/logs 是否被 rsync 删除、APP_DEBUG 是否误设为 true、以及 php-fpm 进程有没有 reload —— 这些细节不会报错,但会让请求静默失败。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











