本文目录导读:

设计一个 PHP 应用的发布流水线(CI/CD),核心目标是自动化构建、测试和部署,最终实现快速、可靠、可追溯的交付。
以下是一套从开发到生产的完整流程设计,涵盖了从代码提交到用户访问的每一个环节。
核心流程概览
graph TD
A[开发者推送代码 (GIT)] --> B[触发 CI/CD]
B --> C{质量门禁}
C -->|失败| D[通知反馈]
C -->|通过| E[构建与打包]
E --> F[部署到测试环境]
F --> G[自动化测试 - 功能/接口]
G -->|失败| D
G -->|通过| H[部署到预生产环境]
H --> I[集成测试与验收]
I -->|失败| D
I -->|通过| J[部署到生产环境]
J --> K[金丝雀/滚动发布]
K --> L[健康检查与监控]
L -->|异常| M[自动回滚]
M --> D
详细阶段设计
代码管理阶段
- 分支策略(推荐
GitFlow或TrunkBased):main/master:主分支,保持可随时部署状态。develop:开发分支。feature/*:功能分支。release/*:预发布分支。- 改动经过 Pull Request 合并,必须通过 Code Review。
- 提交规范:强制使用 Conventional Commits(
feat:,fix:),用于自动生成 Changelog 和语义化版本号(SemVer)。
持续集成阶段 (Continuous Integration)
阶段目标:在每次 push 或 PR 时,自动执行全量检查。
- 触发条件:代码推送到分支或
PR被创建。 - 执行步骤:
- 环境准备:拉取最新代码,指定 PHP 版本(如 8.2/8.3)。
- 依赖安装:执行
composer install --prefer-dist --no-interaction --no-scripts。 - 静态分析:执行
phpstan analyse src/ --level=max(或psalm),检测潜在 bug。 - 代码规范:执行
php-cs-fixer fix --dry-run --diff(或phpcs),确保代码风格统一。 - 敏感信息扫描:检测代码中是否有
.env文件、密码等泄露(使用 Gitleaks 或类似工具)。 - 单元测试:执行
php artisan test --testsuite=Unit(Laravel)或phpunit,覆盖核心业务逻辑。 - 依赖审计:执行
composer audit,检查依赖包是否已发现漏洞(如 RCE 漏洞、XSS 漏洞)。
构建与制品阶段 (Build & Artifact)
由于 PHP 是解释型语言,这一步主要是打包和优化,而非编译,推荐使用 Docker 镜像 作为唯一交付物。
- 构建步骤:
- 选择基础镜像:
php:8.3-fpm-alpine或更稳定的自定义镜像。 - 复制代码:将宿主机优化后的代码(去除开发依赖、测试文件、.git 目录)复制进镜像。
- 优化:
- 移除
require-dev依赖:composer install --no-dev --optimize-autoloader。 - 生成
OPcache预加载文件(如适用)。 - 执行
php artisan config:cache、route:cache、view:cache(Laravel 框架)。
- 移除
- 推送制品:将 Docker 镜像
php-app:latest和php-app:$GIT_COMMIT_SHA推送到私有镜像仓库(Harbor / ECR / ACR)。
- 选择基础镜像:
部署与发布阶段 (Continous Deployment/Delivery)
阶段目标:将镜像部署到不同环境。
-
环境划分:
- 测试环境:每次合并到
develop分支自动部署。 - 预生产环境:打
release/*标签时手动触发。 - 生产环境:打
v1.2.0标签或手动点击发布时触发。
- 测试环境:每次合并到
-
部署策略:
- 零停机部署:使用 Kubernetes 进行滚动更新(Rolling Update)或 蓝绿部署。
- 金丝雀发布:通过 K8s 的 Service Mesh(如 Istio)将 5%~10% 的流量发往新版本,观察指标(错误率、延迟)后再全量切换。
- 配置管理:配置文件(
.env)不进入镜像,通过 K8s ConfigMap 和 Secret 注入,或者 Consul/拉取方式管理。
自动化测试阶段 (Automated Testing)
- 单元测试(已在 CI 阶段执行)。
- 集成测试(部署到测试环境后):
- 执行
php artisan test --testsuite=Feature。 - 执行 API 接口测试(Postman/Newman 或 Pest)。
- 执行数据库迁移测试:在隔离数据库中执行迁移脚本,确保 SQL 兼容。
- 执行
- 端到端测试(E2E):使用 Playwright/Cypress 模拟用户点击行为,验证核心业务流程(如登录、结账)。
监控与告警 (Observability)
阶段目标:确保发布后的稳定运行。
- 日志监控:ELK 或 Grafana Loki,收集 FPM 错误日志和应用日志。
- 指标监控:Prometheus 收集
php-fpm_status、opcache命中率、响应时间、QPS(每秒查询数)、CPU/内存使用率。 - APM(应用性能监控):集成 Sentry(捕获异常)和 Skywalking/New Relic(追踪链路)。
- 告警规则:
- P1(严重):5xx 错误率 > 5%,持续 5 分钟。
- P2(警告):P95 响应时间 > 500ms,持续 10 分钟。
- 主动健康检查:配置 K8s
readinessProbe和livenessProbe,检测/health接口。
回滚机制 (Rollback Strategy)
- 数据库回滚:通常无法自动回滚,需要团队介入评估。
- 应用回滚:通过修改 K8s 镜像 Tag 回滚到上一个版本(
kubectl rollout undo deployment/php-app)。 - 前置条件:发布前必须备份数据库,尤其是在有数据迁移脚本时。
技术选型工具清单
| 项目 | 推荐工具 | 备选工具 |
|---|---|---|
| CI/CD | GitLab CI / GitHub Actions | Jenkins, 阿里云效, 腾讯云 CODING |
| 容器化 | Docker | Podman |
| 编排 | Kubernetes (K8s) / Docker Compose(小规模) | Rancher, 云厂商托管集群 |
| 代码质量 | PHPStan / Psalm / PHP_CodeSniffer | SonarQube |
| 测试 | PHPUnit / Pest | Codeception |
| 制品仓库 | Harbor(私有)/ Docker Hub / AWS ECR | |
| 监控 | Prometheus + Grafana / Sentry | Zabbix(传统)、ELK(日志) |
| 安全扫描 | Gitleaks(密钥扫描) / Trivy(镜像漏洞扫描) | Snyk / Sonatype |
最佳实践与避坑指南
-
自动化数据库迁移:
- 使用
php artisan migrate时,需要考虑长表锁问题,建议将schema变更分为发布前、发布后两步,或者使用gh-ost(针对 MySQL)这样的工具进行在线 DDL。 - 建议将数据库迁移与代码部署分离,允许 Ahead-of-Time 迁移。
- 使用
-
环境一致性:
- 必须在 CI 中使用与你生产环境相同的 PHP 版本和扩展,避免“本地能跑,线上挂”。
- 严格将软件版本(PHP)+ 依赖包版本(Composer.lock)固定下来。
-
文件权限与存储:
- PHP-FPM 运行用户(如
www-data)需要正确设置,防止权限错误。 - 存储分离:
/public/uploads或日志目录必须挂载到云存储(OSS)或 PVC(持久化卷)中,不能存进容器(容器销毁数据即丢失)。
- PHP-FPM 运行用户(如
-
缓存管理:
- 发布后需要清除 OPCache,否则新代码可能不会被加载。
- 配置 Redis/Memcached,在部署脚本中执行
redis-cli FLUSHALL(需谨慎,最好只刷新业务前缀)。
-
灰度发布与 AB 测试:
针对 PHP 应用,可以利用 Nginx 层或 K8s Service 做端口分流,对不同用户 IP 给予不同版本的响应。
一个完整的 PHP 发布流水线应该遵循以下思路:
- 代码提交 -> 触发静态检查与单元测试(防止烂代码进入主干)。
- 构建镜像 -> 将所有依赖打包成不可变容器(保证环境一致性)。
- 环境流转 -> 测试 -> 预生产 -> 生产,层层推进(降低故障半径)。
- 金丝雀/滚动发布 -> 监控 -> 自动回滚(确保稳定性,容忍失败)。
如果您的项目是传统物理机部署(无 K8s),可以使用 GitLab CI + SSH + Ansible 替代:通过 Ansible 编写 Playbook,git pull 更新代码,composer install --no-dev 安装依赖,php artisan migrate --force 执行迁移,echo "" > cache 重置 OPCache,这套简化的流水线同样有效。