# 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' ```