# ============================================================ # Jenkins 生产环境编排(加固版) # 部署位置: 139.155.109.62:/home/novalon/docker-app/jenkins/ # 访问地址: https://ci.f.novalon.cn # # 相对现状(2026-09-14 实测)的修复点: # 1. user: root -> 1000:1000(现状以 root 运行,容器内即宿主 root) # 2. 摘掉 /var/run/docker.sock(作业 config.xml 实测 0 处 docker 调用,纯多余风险; # 挂载 docker.sock = 容器内任意用户可直接拿到宿主 root) # 3. 摘掉 /root/.ssh 全量挂载 -> 改为专用部署密钥只读挂载 # 4. 补日志轮转(现状无 logging 配置,jenkins_home 已 430MB 且裸奔) # 5. 补资源限制、cap_drop、CSRF、JCasC 声明式配置 # # ⚠️ 首次切换到非 root 前必须先改卷属主(否则 Jenkins 起不来): # docker stop jenkins # docker run --rm -v jenkins_jenkins_home:/v alpine chown -R 1000:1000 /v # docker compose -f docker-compose.jenkins.yml up -d # # 用法: # cp .env.example .env && vim .env # docker compose -f docker-compose.jenkins.yml up -d # ============================================================ services: jenkins: # 锁定 LTS 大版本;升级走镜像 tag 变更 + 蓝绿验证,不要用 latest 漂移 image: jenkins/jenkins:2.568.1-lts-jdk17 container_name: jenkins restart: unless-stopped stop_grace_period: 60s # 不再以 root 运行 user: "1000:1000" security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: - CHOWN - SETUID - SETGID environment: - TZ=Asia/Shanghai - JAVA_OPTS=-Xmx1024m -Xms256m -Duser.timezone=Asia/Shanghai -Djenkins.install.runSetupWizard=false # 关闭 Jenkins 2.3xx 之后默认禁用的入站代理(JNLP)端口,减少攻击面 - JENKINS_OPTS=--httpPort=8080 # JCasC:声明式安全域 / 授权 / 凭据,杜绝手工漂移 - CASC_JENKINS_CONFIG=/var/jenkins_config/casc.yaml - ADMIN_USER=${JENKINS_ADMIN_USER} - ADMIN_PASSWORD=${JENKINS_ADMIN_PASSWORD} - GITEA_TOKEN=${GITEA_TOKEN} - DEPLOY_SSH_KEY_PASSPHRASE=${DEPLOY_SSH_KEY_PASSPHRASE} volumes: - jenkins_home:/var/jenkins_home # JCasC 只读挂载 - ./jenkins/casc.yaml:/var/jenkins_config/casc.yaml:ro # 专用部署密钥(仅含 id_ed25519_deploy / known_hosts),不再暴露宿主 /root/.ssh - ./jenkins-ssh:/var/jenkins_home/.ssh:ro tmpfs: - /tmp:size=200m,mode=1777 ports: # 只监听本机,由 nginx 终止 TLS;50000 为 JNLP 入站代理,无 agent 时可整段删除 - "127.0.0.1:8080:8080" - "127.0.0.1:50000:50000" cpus: 2.0 mem_limit: 2g mem_reservation: 512m networks: - novalon-network healthcheck: test: ["CMD", "curl", "-fsS", "http://localhost:8080/login"] interval: 30s timeout: 10s retries: 5 start_period: 90s logging: driver: json-file options: max-size: "20m" max-file: "5" compress: "true" volumes: jenkins_home: driver: local networks: novalon-network: external: true