# ============================================================ # 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