本文目录导读:

在 PHP 中实施 GitOps 部署,核心思想是以 Git 仓库作为唯一的真理源(Single Source of Truth),通过自动化流程将代码变更同步到生产环境,以下是针对 PHP 项目的完整 GitOps 部署方案:
基础架构设计
Git仓库 (包含代码+配置)
↓
CI/CD 流水线 (GitHub Actions / GitLab CI)
↓
容器镜像仓库 (Docker Hub / ECR / GCR)
↓
部署控制器 (ArgoCD / Flux / 自建)
↓
Kubernetes / Docker Swarm / 服务器
PHP 项目容器化
Dockerfile 示例
FROM php:8.2-fpm-alpine
# 安装 PHP 扩展
RUN docker-php-ext-install pdo_mysql opcache \
&& docker-php-ext-enable pdo_mysql
# 安装 Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
# 设置工作目录
WORKDIR /var/www/html
# 复制项目文件
COPY . .
# 安装依赖(开发环境)
RUN composer install --no-interaction --prefer-dist
# 生产环境优化
FROM php:8.2-fpm-alpine as production
WORKDIR /var/www/html
COPY --from=0 /var/www/html .
RUN composer install --no-dev --optimize-autoloader --prefer-dist
# Nginx 配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 9000
CMD ["php-fpm"]
部署清单文件(Git 仓库结构)
deploy/
├── base/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── configmap.yaml
├── production/
│ ├── kustomization.yaml
│ └── patch.yaml
└── staging/
├── kustomization.yaml
└── patch.yaml
deployment.yaml 示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-app
spec:
replicas: 3
selector:
matchLabels:
app: php-app
template:
metadata:
labels:
app: php-app
spec:
containers:
- name: php-app
image: registry.example.com/php-app:latest
ports:
- containerPort: 9000
envFrom:
- configMapRef:
name: php-app-config
readinessProbe:
exec:
command:
- php
- -f
- /var/www/html/healthcheck.php
CI/CD 流水线配置
GitHub Actions 示例
name: CI/CD Pipeline
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: mbstring, intl, pdo_mysql
- name: Install Dependencies
run: composer install --no-interaction --prefer-dist
- name: Run Tests
run: |
php artisan test --coverage
if [ -f "phpunit.xml" ]; then ./vendor/bin/phpunit; fi
build-and-push:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker Image
run: |
docker build -t registry.example.com/php-app:${GITHUB_SHA} .
docker build -t registry.example.com/php-app:latest .
- name: Push to Registry
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login registry.example.com -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin
docker push registry.example.com/php-app:${GITHUB_SHA}
docker push registry.example.com/php-app:latest
- name: Update Deploy Repository
run: |
git clone https://github.com/yourorg/php-app-deploy.git
cd php-app-deploy
sed -i "s|image: .*|image: registry.example.com/php-app:${GITHUB_SHA}|g" base/deployment.yaml
git add .
git commit -m "Update image to ${GITHUB_SHA}"
git push
ArgoCD 部署配置
ArgoCD 应用定义
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: php-app
namespace: argocd
spec:
project: default
source:
repoURL: 'https://github.com/yourorg/php-app-deploy.git'
path: production
targetRevision: HEAD
destination:
server: 'https://kubernetes.default.svc'
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
PHP 应用配置管理
ConfigMap 定义
apiVersion: v1 kind: ConfigMap metadata: name: php-app-config data: APP_ENV: production APP_DEBUG: "false" DB_CONNECTION: mysql DB_HOST: database.internal DB_DATABASE: phpapp CACHE_DRIVER: redis QUEUE_CONNECTION: redis SESSION_DRIVER: redis
环境变量管理(.env.php)
<?php
return [
'APP_ENV' => getenv('APP_ENV') ?: 'production',
'APP_DEBUG' => getenv('APP_DEBUG') ?: false,
'DB_HOST' => getenv('DB_HOST') ?: 'localhost',
'CACHE_DRIVER' => getenv('CACHE_DRIVER') ?: 'redis',
];
部署验证与回滚
健康检查脚本
<?php
// healthcheck.php
$healthChecks = [
'file_permissions' => is_writable('/var/www/html/storage'),
'database' => checkDatabaseConnection(),
'cache' => checkCacheConnection(),
];
foreach ($healthChecks as $check => $status) {
if (!$status) {
http_response_code(500);
echo "FAIL: {$check}";
exit(1);
}
}
http_response_code(200);
echo "OK";
回滚命令
# ArgoCD 回滚
kubectl -n argocd get applications php-app -o jsonpath='{.status.history}'
kubectl -n argocd patch applications.argoproj.io php-app --type merge -p '{"spec":{"syncPolicy":{"automated":{"rollback":true}}}}'
# 或手动回滚
kubectl rollout undo deployment/php-app -n production
# Git 回滚
git revert HEAD~1
git push origin main
高级实践
数据库迁移自动化
apiVersion: batch/v1
kind: Job
metadata:
name: php-migration
spec:
template:
spec:
containers:
- name: migration
image: registry.example.com/php-app:latest
command: ["php", "artisan", "migrate", "--force"]
envFrom:
- configMapRef:
name: php-app-config
restartPolicy: Never
灰度发布/金丝雀部署
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: php-app
spec:
replicas: 5
strategy:
canary:
steps:
- setWeight: 20
- pause: {duration: 5m}
- setWeight: 50
- pause: {duration: 10m}
- setWeight: 100
template:
metadata:
labels:
app: php-app
spec:
containers:
- name: php-app
image: registry.example.com/php-app:latest
监控与日志
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: php-app-monitor
spec:
selector:
matchLabels:
app: php-app
endpoints:
- port: metrics
path: /metrics
interval: 30s
安全最佳实践
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
seccompProfile:
type: RuntimeDefault
部署流程图
graph TD
A[开发者推送代码到Git] --> B[CI触发]
B --> C[运行测试]
C --> D{测试通过?}
D -->|是| E[构建镜像并推送]
D -->|否| F[构建失败通知]
E --> G[更新部署仓库]
G --> H[ArgoCD检测变更]
H --> I[拉取最新配置]
I --> J{K8s集群部署}
J --> K[健康检查]
K -->|成功| L[更新DNS/LB]
K -->|失败| M[自动回滚]
工具推荐
- 部署控制器: ArgoCD, Flux CD, Jenkins X
- CI/CD: GitHub Actions, GitLab CI, CircleCI
- 镜像仓库: Docker Hub, Harbor, Amazon ECR
- K8s 管理: Helm, Kustomize, Skaffold
这个方案实现了从代码提交到生产部署的完整自动化,确保所有变更都可追溯、可回滚,并且完全受Git控制。