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
+153
View File
@@ -0,0 +1,153 @@
# ============================================================
# Gitea 生产环境编排(加固版)
# 部署位置: 139.155.109.62:/home/novalon/docker-app/novalon-cicd/
# 访问地址: https://git.f.novalon.cn
#
# 相对现状(2026-09-14 实测)的修复点:
# 1. 凭据外置到 .env,不再内联在 compose 里
# 2. SSH_PORT 22 -> 2222,修正"克隆地址指向宿主 sshd"的错配
# 3. 资源限制改用 compose 原生 cpus/mem_limit(deploy: 段在非 swarm 下被忽略,等于没限制)
# 4. 补 read_only / cap_drop / tmpfs 最小权限
# 5. 补 PostgreSQL 日志轮转与备份卷
#
# 用法:
# cp .env.example .env && vim .env # 填入真实凭据,.env 绝不入库
# docker compose -f docker-compose.gitea.yml up -d
# ============================================================
services:
# ------------------------------------------------------------
# PostgreSQL 17 —— Gitea 唯一数据源
# ------------------------------------------------------------
postgresql:
image: postgres:17-alpine
container_name: postgresql
restart: always
stop_grace_period: 30s
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- CHOWN
- DAC_OVERRIDE
- FOWNER
- SETGID
- SETUID
environment:
POSTGRES_USER: ${GITEA_DB_USER}
POSTGRES_PASSWORD: ${GITEA_DB_PASSWORD}
POSTGRES_DB: ${GITEA_DB_NAME}
POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C"
TZ: Asia/Shanghai
PGTZ: Asia/Shanghai
volumes:
- ./postgresql_data:/var/lib/postgresql/data
- ./postgresql_init:/docker-entrypoint-initdb.d:ro
- ./postgresql_backup:/var/lib/postgresql/backup
tmpfs:
- /tmp:size=100m,mode=1777
# compose 原生限制(非 swarm 下 deploy: 不生效,必须用这两个键)
cpus: 1.0
mem_limit: 2g
mem_reservation: 512m
networks:
- novalon-network
healthcheck:
test:
[
"CMD-SHELL",
"pg_isready -U ${GITEA_DB_USER} -d ${GITEA_DB_NAME} && psql -U ${GITEA_DB_USER} -d ${GITEA_DB_NAME} -c 'SELECT 1'",
]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
compress: "true"
# ------------------------------------------------------------
# Gitea 1.27.x
# ------------------------------------------------------------
gitea:
image: gitea/gitea:1.27.2
container_name: gitea
restart: always
stop_grace_period: 30s
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- CHOWN
- SETUID
- SETGID
environment:
- USER_UID=1000
- USER_GID=1000
- TZ=Asia/Shanghai
- DB_TYPE=postgres
- DB_HOST=postgresql:5432
- DB_NAME=${GITEA_DB_NAME}
- DB_USER=${GITEA_DB_USER}
- DB_PASSWD=${GITEA_DB_PASSWORD}
- SSH_DOMAIN=${GITEA_SSH_DOMAIN}
# 关键修复:必须与宿主实际映射端口一致,否则页面给出的 SSH 克隆地址不可用
- SSH_PORT=2222
- HTTP_PORT=3000
- ROOT_URL=${GITEA_ROOT_URL}
- LFS_START_SERVER=true
- DISABLE_REGISTRATION=true
- REQUIRE_SIGNIN_VIEW=true
- SHOW_REGISTRATION_BUTTON=false
- DEFAULT_KEEP_EMAIL_PRIVATE=true
- DEFAULT_ALLOW_CREATE_ORGANIZATION=false
- CACHE_ADAPTER=memory
- SESSION_PROVIDER=db
- ENABLE_GZIP=true
- MAX_CREATION_LIMIT=100
- GITEA__security__INSTALL_LOCK=true
- GITEA__security__PASSWORD_COMPLEXITY=lower,upper,digit,spec
- GITEA__security__MIN_PASSWORD_LENGTH=12
- GITEA__service__DISABLE_REGISTRATION=true
- GITEA__service__REQUIRE_SIGNIN_VIEW=true
- GITEA__log__LEVEL=info
- GITEA__log__MODE=console
volumes:
- ./gitea/data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
tmpfs:
- /tmp:size=100m,mode=1777
ports:
# 仅 SSH 对外;HTTP 只允许本机,由 nginx 反代终止 TLS
- "2222:22"
- "127.0.0.1:3001:3000"
depends_on:
postgresql:
condition: service_healthy
cpus: 1.0
mem_limit: 1g
mem_reservation: 256m
networks:
- novalon-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
compress: "true"
networks:
novalon-network:
external: true