初始化
This commit is contained in:
226
docs/runbooks/deployment.md
Normal file
226
docs/runbooks/deployment.md
Normal file
@@ -0,0 +1,226 @@
|
||||
# 🚢 Deployment Runbook
|
||||
|
||||
> PHP Hyperf + Swoole + Vue 3 部署流程指南
|
||||
|
||||
---
|
||||
|
||||
## 环境
|
||||
|
||||
| 环境 | URL | 触发 |
|
||||
|------|-----|------|
|
||||
| Development | `localhost:8200` (前端) / `localhost:9501` (后端) | 本地开发 |
|
||||
| Staging | `staging.example.com` | merge to `develop` |
|
||||
| Production | `www.example.com` | merge to `main` |
|
||||
|
||||
## Docker Compose 模板
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# Nginx — 负载均衡 + 静态资源 + SSL
|
||||
nginx:
|
||||
image: nginx:1.25-alpine
|
||||
container_name: app_nginx
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./docker/nginx/conf.d:/etc/nginx/conf.d
|
||||
- ./Case-Database-Frontend-user/dist:/usr/share/nginx/html/user
|
||||
- ./Case-Database-Frontend-admin/dist:/usr/share/nginx/html/admin
|
||||
- ./docker/nginx/ssl:/etc/nginx/ssl
|
||||
depends_on:
|
||||
- hyperf
|
||||
networks:
|
||||
- app_network
|
||||
restart: unless-stopped
|
||||
|
||||
# Hyperf — PHP 8.1 + Swoole (HTTP + WebSocket)
|
||||
hyperf:
|
||||
build:
|
||||
context: ./Case-Database-Backend
|
||||
dockerfile: Dockerfile
|
||||
container_name: app_backend
|
||||
ports:
|
||||
- "9501:9501" # HTTP API
|
||||
- "9502:9502" # WebSocket
|
||||
volumes:
|
||||
- ./Case-Database-Backend:/opt/www
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-production}
|
||||
- DB_HOST=mysql
|
||||
- DB_PORT=3306
|
||||
- DB_DATABASE=${DB_DATABASE}
|
||||
- DB_USERNAME=${DB_USERNAME}
|
||||
- DB_PASSWORD=${DB_PASSWORD}
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
- REDIS_AUTH=${REDIS_AUTH}
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- app_network
|
||||
restart: unless-stopped
|
||||
|
||||
# MySQL 8.1 — 主数据库
|
||||
mysql:
|
||||
image: mysql:8.1
|
||||
container_name: app_mysql
|
||||
ports:
|
||||
- "${DB_PORT:-3307}:3306"
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
|
||||
MYSQL_DATABASE: ${DB_DATABASE}
|
||||
MYSQL_USER: ${DB_USERNAME}
|
||||
MYSQL_PASSWORD: ${DB_PASSWORD}
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
- ./docker/mysql/conf.d:/etc/mysql/conf.d
|
||||
- ./docker/mysql/init:/docker-entrypoint-initdb.d
|
||||
command: >
|
||||
--default-authentication-plugin=caching_sha2_password
|
||||
--character-set-server=utf8mb4
|
||||
--collation-server=utf8mb4_unicode_ci
|
||||
--max-connections=500
|
||||
--innodb-buffer-pool-size=1G
|
||||
--slow-query-log=ON
|
||||
--long-query-time=1
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- app_network
|
||||
restart: unless-stopped
|
||||
|
||||
# Redis 7 — 缓存 + 队列 + Session
|
||||
redis:
|
||||
image: redis:7.2-alpine
|
||||
container_name: app_redis
|
||||
ports:
|
||||
- "${REDIS_PORT:-6379}:6379"
|
||||
command: redis-server --requirepass ${REDIS_AUTH} --maxmemory 512mb --maxmemory-policy allkeys-lru
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "-a", "${REDIS_AUTH}", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- app_network
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
driver: local
|
||||
redis_data:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
app_network:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
## Backend Dockerfile
|
||||
|
||||
```dockerfile
|
||||
FROM hyperf/hyperf:8.1-alpine-v3.18-swoole
|
||||
|
||||
LABEL maintainer="Enterprise Digital Platform"
|
||||
|
||||
ENV TIMEZONE=Asia/Shanghai
|
||||
ENV APP_ENV=production
|
||||
|
||||
WORKDIR /opt/www
|
||||
|
||||
COPY composer.json composer.lock ./
|
||||
RUN composer install --no-dev --optimize-autoloader --no-scripts
|
||||
|
||||
COPY . .
|
||||
RUN composer dump-autoload -o
|
||||
|
||||
EXPOSE 9501 9502
|
||||
|
||||
ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"]
|
||||
```
|
||||
|
||||
## 部署检查清单
|
||||
|
||||
### 部署前
|
||||
- [ ] 所有后端测试通过 (`composer test`)
|
||||
- [ ] 所有前端测试通过 (`npm test`)
|
||||
- [ ] 代码审查已批准
|
||||
- [ ] 数据库迁移已准备 (`php bin/hyperf.php migrate:status`)
|
||||
- [ ] 环境变量已配置 (`.env`)
|
||||
- [ ] Redis 连接正常
|
||||
- [ ] 静态分析通过 (`composer analyse`)
|
||||
|
||||
### 部署步骤
|
||||
```bash
|
||||
# 1. 拉取最新代码
|
||||
git pull origin main
|
||||
|
||||
# 2. 后端依赖更新
|
||||
cd Case-Database-Backend && composer install --no-dev -o
|
||||
|
||||
# 3. 数据库迁移
|
||||
php bin/hyperf.php migrate
|
||||
|
||||
# 4. 前端构建
|
||||
cd Case-Database-Frontend-user && npm ci && npm run build
|
||||
cd ../Case-Database-Frontend-admin && npm ci && npm run build
|
||||
|
||||
# 5. 重启服务
|
||||
docker-compose restart hyperf
|
||||
docker-compose restart nginx
|
||||
|
||||
# 6. 验证
|
||||
curl -s https://your-domain.com/admin/health | jq
|
||||
```
|
||||
|
||||
### 部署后
|
||||
- [ ] 健康检查通过
|
||||
- [ ] 监控无异常 (CPU/内存/连接数)
|
||||
- [ ] 数据库迁移成功
|
||||
- [ ] WebSocket 连接正常
|
||||
- [ ] 队列消费进程运行中
|
||||
|
||||
## 回滚
|
||||
|
||||
```bash
|
||||
# 代码回滚
|
||||
git revert HEAD
|
||||
git push origin main
|
||||
|
||||
# 数据库回滚
|
||||
php bin/hyperf.php migrate:rollback --step=1
|
||||
|
||||
# Docker 容器回滚到上一个镜像
|
||||
docker-compose pull hyperf
|
||||
docker-compose up -d hyperf
|
||||
```
|
||||
|
||||
## 扩展到多实例
|
||||
|
||||
```bash
|
||||
# 水平扩展 Hyperf 实例
|
||||
docker-compose up -d --scale hyperf=3
|
||||
|
||||
# Nginx upstream 配置多后端
|
||||
upstream hyperf_cluster {
|
||||
server hyperf_1:9501;
|
||||
server hyperf_2:9501;
|
||||
server hyperf_3:9501;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*最后更新: YYYY-MM-DD*
|
||||
Reference in New Issue
Block a user