- infra/cicd:docker-compose(gitea/jenkins)、JCasC(凭据统一 ${ENV} 注入,无硬编码)、
备份/恢复、健康检查、凭据轮换与 git 历史清除脚本
- docs/deployment/cicd:安装、高可用备份监控、凭据事故复盘
- .env.example 仅为占位模板;真实 .env 由 .gitignore 排除
CI/CD 生产环境:Gitea + Jenkins 运维文档
基准日期:2026-09-14。本文所有数据来自对生产服务器
139.155.109.62的实测(SSH 探测 + HTTP 探测), 非泛泛的最佳实践摘抄。配置源码在infra/cicd/。
文档索引
| 文档 | 内容 |
|---|---|
| 01-installation.md | 安装部署、安全加固、Gitea↔Jenkins 集成、webhook 排障 |
| 02-ha-backup-monitoring.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.shrsync 发布 - 反代与 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) |
| 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 + 应用) |
低优先 |
快速操作
# 备份(薄:仅 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'