chore(infra): 新增 Gitea+Jenkins CI/CD 部署与凭据整改

- infra/cicd:docker-compose(gitea/jenkins)、JCasC(凭据统一 ${ENV} 注入,无硬编码)、
  备份/恢复、健康检查、凭据轮换与 git 历史清除脚本
- docs/deployment/cicd:安装、高可用备份监控、凭据事故复盘
- .env.example 仅为占位模板;真实 .env 由 .gitignore 排除
This commit was merged in pull request #27.
This commit is contained in:
2026-09-20 10:37:57 +08:00
parent 7df2dde438
commit 4ab2f3cd8e
15 changed files with 2092 additions and 0 deletions
+86
View File
@@ -0,0 +1,86 @@
# CI/CD 生产环境:Gitea + Jenkins 运维文档
> 基准日期:2026-09-14。本文所有数据来自对生产服务器 `139.155.109.62` 的实测(SSH 探测 + HTTP 探测),
> 非泛泛的最佳实践摘抄。配置源码在 [`infra/cicd/`](../../../infra/cicd/)。
## 文档索引
| 文档 | 内容 |
|------|------|
| [01-installation.md](01-installation.md) | 安装部署、安全加固、Gitea↔Jenkins 集成、webhook 排障 |
| [02-ha-backup-monitoring.md](02-ha-backup-monitoring.md) | 高可用、备份与恢复、日志与监控 |
| [03-credential-incident.md](03-credential-incident.md) | **P0**:凭据入库事故与处置清单(待执行) |
## 当前架构(实测)
```
┌────────────────────────────────────┐
│ 139.155.109.62 (VM-0-15-debian) │
│ Debian · Docker 20.10.24 │
│ │
推送 git push ────────┐│ novalon-nginx-secure (nginx:alpine)│
│ :80/:443 终止 TLS + HSTS │
│ └──────┬──────────────┬──────────────┘
│ │ │
│ git.f.novalon.cn ci.f.novalon.cn
│ │ │
│ upstream gitea_app upstream jenkins_app
│ │ │
│ ┌───────▼─────┐ ┌─────▼──────┐
│ │ gitea │ │ jenkins │
└─────────►│ 1.27.2 │ │ 2.568.1 │
│ :3001(本机) │ │ :8080(本机) │
│ :2222 SSH │ └─────┬──────┘
└───────┬─────┘ │
│ │ rsync+ssh
┌───────▼─────┐ │
│ postgresql │ ▼
│ 17-alpine │ /home/novalon/docker-app/
└─────────────┘ novalon-website(Next.js)
```
- 代码仓库:`git.f.novalon.cn/novalon/novalon-website`(本仓库 `origin` 即指向此处)
- 流水线:`Jenkinsfile`(仓库根目录),作业名 `novalon-website-ci-cd`
- 触发:Gitea push → webhook → Jenkins `GenericTrigger` → 构建/测试 → `scripts/deploy.sh` rsync 发布
- 反代与 TLS:`nginx-static-production.conf` 定义 upstream,`conf.d/*.conf` 定义 server 块
## 2026-09-14 审计结论
### 已就绪(无需改动)
| 项 | 实测证据 |
|----|----------|
| HTTPS + HSTS | 两域名均 `strict-transport-security: max-age=63072000` |
| Gitea Cookie 安全 | `i_like_gitea` 带 `HttpOnly; Secure; SameSite=Lax` |
| 作业与插件齐备 | `gitea`、`generic-webhook-trigger`、`credentials-binding` 已装 |
| 反向代理信任链 | `REVERSE_PROXY_TRUSTED_PROXIES=172.20.0.0/16,127.0.0.1` |
| 服务端口不外暴 | Gitea/Jenkins HTTP 均仅 `127.0.0.1`,只有 nginx 占 80/443 |
### 发现的问题(按严重度)
| 级别 | 问题 | 证据 | 状态 |
|------|------|------|------|
| **P0** | 真实凭据已提交 git 并推送公网 | `cicd.config` Gitea/Jenkins 密码、OAuth2 secret | 待处置([03](03-credential-incident.md)) |
| **P0** | Jenkins 从未备份 | `backup.sh` 存在但 crontab 无此项,`/home/novalon/backups/` 不存在 | ✅ 已修复 |
| **P1** | 磁盘 20G 用 85–90% | `df -h /` → 88% used, 2.4G avail | ⚠️ 需扩容/异地 |
| **P1** | Jenkins 以 root 运行 + 挂 docker.sock + /root/.ssh | compose `user: root`;作业实测 0 处 docker 调用 | 配置已备好,待维护窗口 |
| **P1** | Gitea SSH 克隆地址不可用 | `app.ini SSH_PORT=22`,实际暴露 `0.0.0.0:2222` | 配置已备好 |
| **P2** | 容器日志轮转未生效 | Gitea 单份日志 849MB(compose 配置在,运行容器 `LogConfig={}`) | ✅ 已截断+兜底 cron |
| **P2** | Gitea 数据库零备份 | `postgresql_backup/` 为空 | ✅ 已修复 |
| **P3** | 安全头重复注入 | Gitea 响应 `x-frame-options` 出现两次(nginx + 应用) | 低优先 |
## 快速操作
```bash
# 备份(薄:仅 DB + Jenkins 配置,约 2MB)
ssh root@139.155.109.62 '/home/novalon/docker-app/infra/cicd/backup/backup-cicd.sh --skip-repos'
# 备份(全量:含 Gitea 裸库,约 940MB)
ssh root@139.155.109.62 '/home/novalon/docker-app/infra/cicd/backup/backup-cicd.sh'
# 健康检查(6 维度,FAIL 时 exit 1)
ssh root@139.155.109.62 '/home/novalon/docker-app/infra/cicd/monitoring/healthcheck-cicd.sh'
# 已装的定时任务
ssh root@139.155.109.62 'crontab -l | grep infra/cicd'
```