Files
novalon-website/infra/cicd/docker-compose.gitea.yml
T
zhangxiang 4ab2f3cd8e chore(infra): 新增 Gitea+Jenkins CI/CD 部署与凭据整改
- infra/cicd:docker-compose(gitea/jenkins)、JCasC(凭据统一 ${ENV} 注入,无硬编码)、
  备份/恢复、健康检查、凭据轮换与 git 历史清除脚本
- docs/deployment/cicd:安装、高可用备份监控、凭据事故复盘
- .env.example 仅为占位模板;真实 .env 由 .gitignore 排除
2026-09-20 10:37:57 +08:00

154 lines
4.6 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ============================================================
# 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_limitdeploy: 段在非 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