diff --git a/.ci-config.yml b/.ci-config.yml new file mode 100644 index 0000000..e1d577f --- /dev/null +++ b/.ci-config.yml @@ -0,0 +1,144 @@ +# CI/CD项目配置文件 +# 文件名: .ci-config.yml +# 放置在项目根目录 + +# 项目基本信息 +project: + name: "jenkins-demo" + type: "java-maven" # 支持: java-maven, java-gradle, nodejs, python, dotnet + version: "1.0.0" + description: "Spring Boot演示项目" + +# 构建配置 +build: + # JDK版本(java项目专用) + jdk: "17" + + # Maven配置(java-maven项目专用) + maven: + goals: ["clean", "compile", "test", "package"] + profiles: ["default"] + skip_tests: false + + # Node.js配置(nodejs项目专用) + nodejs: + version: "18" + package_manager: "npm" # npm, yarn, pnpm + build_command: "npm run build" + test_command: "npm test" + + # Python配置(python项目专用) + python: + version: "3.9" + requirements_file: "requirements.txt" + test_command: "pytest" + + # 自定义构建命令 + custom_commands: + pre_build: [] + post_build: [] + +# 测试配置 +test: + unit_tests: + enabled: true + command: "mvn test" + reports: "target/surefire-reports/*.xml" + + integration_tests: + enabled: true + command: "mvn verify -Pintegration-test" + reports: "target/failsafe-reports/*.xml" + + coverage: + enabled: true + tool: "jacoco" # jacoco, cobertura + threshold: 80 + reports: "target/site/jacoco/jacoco.xml" + +# 代码质量 +quality: + sonarqube: + enabled: true + project_key: "jenkins-demo" + host_url: "http://116.62.163.84:15010" + quality_gate: true + + checkstyle: + enabled: false + config_file: "checkstyle.xml" + + spotbugs: + enabled: false + +# Docker配置 +docker: + enabled: true + dockerfile: "Dockerfile" + image_name: "jenkins-demo" + registry: "" # 私有镜像仓库地址,空表示本地 + build_args: {} + +# 部署配置 +deploy: + target: "test" # test, staging, production + + # 测试环境 + test: + server: "116.62.163.84" + port: 8080 + health_check: "/api/health" + container_name: "jenkins-demo-test" + + # 预发布环境 + staging: + server: "116.62.163.84" + port: 8090 + health_check: "/api/health" + container_name: "jenkins-demo-staging" + + # 生产环境 + production: + server: "116.62.163.84" + port: 80 + health_check: "/api/health" + container_name: "jenkins-demo-prod" + manual_approval: true + +# 通知配置 +notifications: + email: + enabled: false + recipients: ["dev-team@company.com"] + + slack: + enabled: false + channel: "#ci-cd" + webhook_url: "" + + dingtalk: + enabled: false + webhook_url: "" + secret: "" + +# 高级配置 +advanced: + # 并行构建 + parallel_builds: true + + # 缓存配置 + cache: + maven_repository: true + node_modules: true + pip_cache: true + + # 安全扫描 + security: + dependency_check: true + image_scan: true + + # 构建超时(分钟) + timeout: 30 + + # 保留构建数量 + build_retention: 10 diff --git a/ENTERPRISE_JENKINS_GUIDE.md b/ENTERPRISE_JENKINS_GUIDE.md new file mode 100644 index 0000000..b7d98e1 --- /dev/null +++ b/ENTERPRISE_JENKINS_GUIDE.md @@ -0,0 +1,268 @@ +# 企业级Jenkins CI/CD平台配置指南 + +## 🎯 平台特性 + +### ✅ 企业级功能 +- **配置即代码**:使用JCasC实现Jenkins配置自动化 +- **多项目类型支持**:Java Maven/Gradle、Node.js、Python、.NET +- **通用Pipeline模板**:无需编写复杂Jenkinsfile +- **安全扫描集成**:依赖检查、镜像安全扫描 +- **多环境部署**:测试、预发布、生产环境自动化部署 +- **通知集成**:邮件、Slack、钉钉等多种通知方式 + +### ✅ 开发友好 +- **简化配置**:项目只需维护 `.ci-config.yml` 文件 +- **自动检测**:自动识别项目类型和构建工具 +- **并行构建**:支持多阶段并行执行,提升构建速度 +- **智能缓存**:Maven仓库、Node模块等智能缓存 + +## 🚀 快速部署 + +### 1. 一键部署命令 +```bash +# 克隆项目 +git clone http://116.62.163.84:15006/wangtianqi/java_demo.git +cd java_demo/jenkins-docker + +# 执行部署脚本 +chmod +x deploy-enterprise.sh +./deploy-enterprise.sh +``` + +### 2. 手动部署步骤 +```bash +# 构建镜像 +docker-compose build + +# 启动服务 +docker-compose up -d + +# 查看状态 +docker-compose ps +``` + +## 🔧 项目接入指南 + +### 1. 创建项目配置文件 +在项目根目录创建 `.ci-config.yml`: + +```yaml +project: + name: "my-project" + type: "java-maven" # 或 java-gradle, nodejs, python + +build: + jdk: "17" # Java项目专用 + +test: + unit_tests: + enabled: true + coverage: + threshold: 80 + +docker: + enabled: true + image_name: "my-project" + +deploy: + target: "test" +``` + +### 2. 创建简化Jenkinsfile +```groovy +// 项目根目录的 Jenkinsfile +@Library('ci-cd-shared-library') _ + +def pipelineTemplate = libraryResource 'templates/universal-pipeline.groovy' +evaluate(pipelineTemplate) +``` + +### 3. 在Jenkins中创建Pipeline +1. 新建Pipeline项目 +2. 配置Git仓库 +3. 指定Jenkinsfile路径 +4. 保存并构建 + +## 📋 支持的项目类型 + +### Java Maven项目 +```yaml +project: + type: "java-maven" +build: + jdk: "17" + maven: + goals: ["clean", "compile", "test", "package"] + profiles: ["default"] +``` + +### Java Gradle项目 +```yaml +project: + type: "java-gradle" +build: + jdk: "17" + gradle: + tasks: ["clean", "build", "test"] +``` + +### Node.js项目 +```yaml +project: + type: "nodejs" +build: + nodejs: + version: "18" + package_manager: "npm" + build_command: "npm run build" + test_command: "npm test" +``` + +### Python项目 +```yaml +project: + type: "python" +build: + python: + version: "3.9" + requirements_file: "requirements.txt" + test_command: "pytest" +``` + +## 🔐 安全配置 + +### 1. 凭据管理 +平台预配置了以下凭据类型: +- Git仓库访问凭据 +- SSH部署凭据 +- SonarQube访问令牌 +- Docker仓库凭据 + +### 2. 权限控制 +- **管理员**:完整系统权限 +- **开发人员**:项目构建和查看权限 +- **只读用户**:仅查看权限 + +### 3. 安全扫描 +- **依赖漏洞扫描**:自动检查第三方依赖安全问题 +- **Docker镜像扫描**:检查镜像中的安全漏洞 +- **代码质量门禁**:SonarQube质量门禁 + +## 🔄 CI/CD流程 + +### 标准流程 +1. **代码检出**:从Git仓库获取最新代码 +2. **环境检测**:自动检测和配置构建环境 +3. **并行分析**: + - 代码编译 + - 代码质量检查 +4. **并行测试**: + - 单元测试 + - 集成测试 +5. **SonarQube分析**:代码质量和安全分析 +6. **制品构建**: + - 应用打包 + - Docker镜像构建 +7. **安全扫描**: + - 依赖安全扫描 + - 镜像安全扫描 +8. **自动部署**:根据分支策略自动部署 +9. **部署验证**:健康检查和功能验证 + +### 分支策略 +- **main/master**:部署到生产环境(需要人工确认) +- **develop**:部署到测试环境 +- **feature/***:运行测试,不部署 +- **release/***:部署到预发布环境 + +## 📊 监控和通知 + +### 构建监控 +- 构建状态实时显示 +- 构建历史和趋势分析 +- 测试报告和覆盖率报告 +- 代码质量趋势 + +### 通知集成 +支持多种通知方式: +```yaml +notifications: + email: + enabled: true + recipients: ["team@company.com"] + slack: + enabled: true + channel: "#ci-cd" + dingtalk: + enabled: true + webhook_url: "your-webhook-url" +``` + +## 🛠️ 日常运维 + +### 服务管理 +```bash +# 启动服务 +./start.sh + +# 停止服务 +./stop.sh + +# 重启服务 +./restart.sh + +# 查看日志 +./logs.sh # Jenkins日志 +./logs.sh sonar # SonarQube日志 + +# 备份数据 +./backup.sh +``` + +### 系统优化 +1. **内存调优**:根据项目数量调整Jenkins内存 +2. **并发控制**:配置合适的执行器数量 +3. **缓存策略**:启用Maven、npm等缓存 +4. **清理策略**:定期清理旧构建和工作空间 + +## 🔧 故障排查 + +### 常见问题 +1. **构建失败**:检查项目配置和依赖 +2. **部署失败**:验证SSH凭据和目标服务器 +3. **插件问题**:重启Jenkins或重新安装插件 +4. **性能问题**:增加内存或优化构建脚本 + +### 调试技巧 +```bash +# 查看容器状态 +docker-compose ps + +# 查看详细日志 +docker-compose logs -f jenkins + +# 进入容器调试 +docker exec -it jenkins-custom bash + +# 检查网络连接 +docker exec jenkins-custom curl -I http://116.62.163.84:15010 +``` + +## 🚀 扩展开发 + +### 自定义Pipeline模板 +1. 修改 `pipeline-templates/universal-pipeline.groovy` +2. 添加新的项目类型支持 +3. 扩展部署策略 + +### 共享库开发 +1. 创建Jenkins共享库项目 +2. 实现通用构建方法 +3. 在Jenkins中配置共享库 + +### 插件集成 +1. 在Dockerfile中添加新插件 +2. 在JCasC配置中添加插件配置 +3. 重新构建Jenkins镜像 + +这个企业级配置提供了完整的CI/CD解决方案,支持快速接入新项目,无需复杂的Jenkinsfile编写。 diff --git a/Jenkinsfile b/Jenkinsfile index af7351c..a4de048 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -11,17 +11,18 @@ pipeline { // 使用系统默认或Jenkins节点上已安装的JDK // 不再强制指定JAVA_HOME,让Jenkins自动检测 - // 目标服务器配置 - DEPLOY_SERVER = '116.62.163.84' + // 目标服务器配置 DEPLOY_SERVER = '116.62.163.84' // Docker相关环境变量 IMAGE_NAME = 'jenkins-demo' - IMAGE_TAG = "${BUILD_NUMBER}" + IMAGE_TAG = "${BUILD_NUMBER}" + // SonarQube配置 SONAR_HOST_URL = 'http://116.62.163.84:15010' SONAR_PROJECT_KEY = 'jenkins-demo' SONAR_TOKEN = 'squ_7e4217cabd0faae6f3b8ee359b3b8e2ac52eb69a' - } + } + // 使用Jenkins中配置的工具(自动安装) tools { maven 'Maven-3.9.6' // 使用您在Jenkins中配置的Maven名称 @@ -164,22 +165,16 @@ pipeline { echo '📤 传输Docker镜像到目标服务器...' script { // 将Docker镜像保存为tar文件并传输到目标服务器 - withCredentials([usernamePassword(credentialsId: 'deploy-server-ssh', usernameVariable: 'SSH_USER', passwordVariable: 'SSH_PASS')]) { + sshagent(['deploy-server-ssh-key']) { sh ''' # 保存Docker镜像为tar文件 docker save ${IMAGE_NAME}:${IMAGE_TAG} -o ${IMAGE_NAME}-${IMAGE_TAG}.tar - # 安装sshpass(如果未安装) - command -v sshpass >/dev/null 2>&1 || { - echo "安装sshpass..." - apt-get update && apt-get install -y sshpass || yum install -y sshpass || true - } - # 传输镜像文件到目标服务器 - sshpass -p "$SSH_PASS" scp -o StrictHostKeyChecking=no ${IMAGE_NAME}-${IMAGE_TAG}.tar ${SSH_USER}@${DEPLOY_SERVER}:/tmp/ + scp -o StrictHostKeyChecking=no ${IMAGE_NAME}-${IMAGE_TAG}.tar root@${DEPLOY_SERVER}:/tmp/ # 在目标服务器上加载镜像 - sshpass -p "$SSH_PASS" ssh -o StrictHostKeyChecking=no ${SSH_USER}@${DEPLOY_SERVER} << EOF + ssh -o StrictHostKeyChecking=no root@${DEPLOY_SERVER} << EOF # 加载Docker镜像 docker load -i /tmp/${IMAGE_NAME}-${IMAGE_TAG}.tar @@ -212,9 +207,9 @@ EOF echo '🚀 部署到测试环境...' script { // 部署到测试服务器 - withCredentials([usernamePassword(credentialsId: 'deploy-server-ssh', usernameVariable: 'SSH_USER', passwordVariable: 'SSH_PASS')]) { + sshagent(['deploy-server-ssh-key']) { sh ''' - sshpass -p "$SSH_PASS" ssh -o StrictHostKeyChecking=no ${SSH_USER}@${DEPLOY_SERVER} << EOF + ssh -o StrictHostKeyChecking=no root@${DEPLOY_SERVER} << EOF # 停止现有容器 docker stop jenkins-demo-test || true docker rm jenkins-demo-test || true @@ -249,9 +244,9 @@ EOF parameters: [choice(name: 'DEPLOY_ENV', choices: ['prod'], description: '选择部署环境')] // 部署到生产服务器 - withCredentials([usernamePassword(credentialsId: 'deploy-server-ssh', usernameVariable: 'SSH_USER', passwordVariable: 'SSH_PASS')]) { + sshagent(['deploy-server-ssh-key']) { sh ''' - sshpass -p "$SSH_PASS" ssh -o StrictHostKeyChecking=no ${SSH_USER}@${DEPLOY_SERVER} << EOF + ssh -o StrictHostKeyChecking=no root@${DEPLOY_SERVER} << EOF # 备份当前版本 docker tag ${IMAGE_NAME}:latest ${IMAGE_NAME}:backup-$(date +%Y%m%d-%H%M%S) || true diff --git a/Jenkinsfile.template b/Jenkinsfile.template new file mode 100644 index 0000000..86f26f8 --- /dev/null +++ b/Jenkinsfile.template @@ -0,0 +1,9 @@ +/** + * 简化版Jenkinsfile + * 所有复杂逻辑都在共享库和模板中处理 + * 项目只需要维护 .ci-config.yml 配置文件 + */ + +// 加载通用Pipeline模板 +def pipelineTemplate = libraryResource 'templates/universal-pipeline.groovy' +evaluate(pipelineTemplate) diff --git a/SSH_CONFIG_GUIDE.md b/SSH_CONFIG_GUIDE.md new file mode 100644 index 0000000..94f436f --- /dev/null +++ b/SSH_CONFIG_GUIDE.md @@ -0,0 +1,68 @@ +# Jenkins SSH私钥配置指南 + +## 🔑 配置SSH私钥凭据 + +### 步骤1:在Jenkins中添加SSH私钥 + +1. **进入Jenkins管理界面** + - 访问:`Jenkins首页 -> Manage Jenkins -> Credentials` + +2. **选择凭据域** + - 点击 `(global)` 域 + - 点击 `Add Credentials` + +3. **配置SSH私钥凭据** + ``` + Kind: SSH Username with private key + Scope: Global + ID: deploy-server-ssh-key + Description: 部署服务器SSH私钥 + Username: root + Private Key: 选择 "Enter directly" + ``` + +4. **粘贴私钥内容** + 将管理员给您的完整私钥内容粘贴到文本框中: + ``` + -----BEGIN RSA PRIVATE KEY----- + Proc-Type: 4,ENCRYPTED + DEK-Info: AES-128-CBC,7019400DF1E53152A70764EC3D3BA618 + + qtAjNBXdBBtv+jieZqEP3/QxvsH+4VutSOT4yTyNGTGKb7zyUVJk+ygePnpFe4EU + ... (完整私钥内容) + -----END RSA PRIVATE KEY----- + ``` + +5. **设置私钥密码** + - Passphrase: 输入私钥的解密密码(需要问管理员) + +### 步骤2:修改Jenkinsfile使用SSH私钥 + +我们需要将Jenkinsfile中的用户名密码认证改为SSH私钥认证。 + +## 🚀 优势对比 + +**SSH私钥认证 vs 用户名密码认证:** + +| 特性 | SSH私钥 | 用户名密码 | +|------|---------|------------| +| 安全性 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | +| 便利性 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | +| 企业级 | ✅ 推荐 | ⚠️ 不建议 | +| 密码策略 | 无需考虑 | 需要定期更换 | +| 审计追踪 | 更好 | 一般 | + +## 🛠️ 下一步操作 + +1. **等待当前构建完成**(Maven依赖下载中) +2. **配置SSH私钥凭据**(按上述步骤) +3. **更新Jenkinsfile**(我来帮您修改) +4. **测试SSH连接** + +## 📝 需要确认的信息 + +请向服务器管理员确认: +- SSH私钥的解密密码(passphrase) +- SSH连接的用户名(通常是root) +- 服务器IP:116.62.163.84(已确认) +- SSH端口:22(默认,除非有变更) diff --git a/jenkins-docker/Dockerfile b/jenkins-docker/Dockerfile new file mode 100644 index 0000000..74c6e2c --- /dev/null +++ b/jenkins-docker/Dockerfile @@ -0,0 +1,102 @@ +# 基于官方Jenkins镜像 +FROM jenkins/jenkins:2.426.1-lts + +# 切换到root用户安装软件 +USER root + +# 设置时区 +ENV TZ=Asia/Shanghai +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +# 更新包管理器并安装必要工具 +RUN apt-get update && apt-get install -y \ + openjdk-17-jdk \ + maven \ + curl \ + wget \ + git \ + sshpass \ + vim \ + unzip \ + && rm -rf /var/lib/apt/lists/* + +# 设置JDK环境变量 +ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 +ENV PATH=$JAVA_HOME/bin:$PATH + +# 配置Maven镜像加速(使用阿里云镜像) +RUN mkdir -p /root/.m2 && \ + echo '' > /root/.m2/settings.xml && \ + echo '> /root/.m2/settings.xml && \ + echo ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' >> /root/.m2/settings.xml && \ + echo ' xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">' >> /root/.m2/settings.xml && \ + echo ' ' >> /root/.m2/settings.xml && \ + echo ' ' >> /root/.m2/settings.xml && \ + echo ' aliyunmaven' >> /root/.m2/settings.xml && \ + echo ' *' >> /root/.m2/settings.xml && \ + echo ' 阿里云公共仓库' >> /root/.m2/settings.xml && \ + echo ' https://maven.aliyun.com/repository/public' >> /root/.m2/settings.xml && \ + echo ' ' >> /root/.m2/settings.xml && \ + echo ' ' >> /root/.m2/settings.xml && \ + echo '' >> /root/.m2/settings.xml + +# 验证Java和Maven安装 +RUN java -version && mvn -version + +# 安装Docker CLI(用于Docker in Docker) +RUN curl -fsSL https://get.docker.com -o get-docker.sh && \ + sh get-docker.sh && \ + rm get-docker.sh + +# 将jenkins用户添加到docker组 +RUN usermod -aG docker jenkins + +# 创建jenkins用户的Maven配置 +RUN mkdir -p /var/jenkins_home/.m2 && \ + cp /root/.m2/settings.xml /var/jenkins_home/.m2/ && \ + chown -R jenkins:jenkins /var/jenkins_home/.m2 + +# 切换回jenkins用户 +USER jenkins + +# 预安装核心插件(企业级CI/CD必备) +RUN jenkins-plugin-cli --plugins \ + maven-integration-plugin \ + jacoco \ + sonar \ + docker-workflow \ + docker-plugin \ + ssh-agent \ + credentials-binding \ + git \ + github \ + workflow-aggregator \ + pipeline-stage-view \ + blueocean \ + build-timeout \ + timestamper \ + ws-cleanup \ + ant \ + gradle \ + nodejs \ + publish-over-ssh \ + email-ext \ + slack \ + build-monitor-plugin \ + role-strategy \ + ldap \ + matrix-auth \ + configuration-as-code \ + job-dsl + +# 复制预配置文件 +COPY jenkins-config/ /var/jenkins_home/ + +# 设置Jenkins启动选项 +ENV JAVA_OPTS="-Djenkins.install.runSetupWizard=false -Xmx2048m -Duser.timezone=Asia/Shanghai" +ENV JENKINS_OPTS="--httpPort=8080" + +# 设置Jenkins配置文件权限 +USER root +RUN chown -R jenkins:jenkins /var/jenkins_home/ +USER jenkins diff --git a/jenkins-docker/deploy-enterprise.sh b/jenkins-docker/deploy-enterprise.sh new file mode 100644 index 0000000..cb4c8ee --- /dev/null +++ b/jenkins-docker/deploy-enterprise.sh @@ -0,0 +1,211 @@ +#!/bin/bash +# 企业级Jenkins一键部署脚本 + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" + +echo "🚀 开始部署企业级Jenkins CI/CD平台..." + +# 检查Docker环境 +check_docker() { + if ! command -v docker &> /dev/null; then + echo "❌ Docker未安装,请先安装Docker" + exit 1 + fi + + if ! command -v docker-compose &> /dev/null; then + echo "❌ Docker Compose未安装,请先安装Docker Compose" + exit 1 + fi + + if ! docker info &> /dev/null; then + echo "❌ Docker服务未运行,请启动Docker" + exit 1 + fi +} + +# 创建必要目录 +create_directories() { + echo "📁 创建项目目录结构..." + + mkdir -p "${SCRIPT_DIR}/jenkins_data" + mkdir -p "${SCRIPT_DIR}/jenkins_data/workspace" + mkdir -p "${SCRIPT_DIR}/jenkins_data/jobs" + mkdir -p "${SCRIPT_DIR}/jenkins_data/plugins" + mkdir -p "${SCRIPT_DIR}/sonarqube_data" + + # 设置权限 + sudo chown -R 1000:1000 "${SCRIPT_DIR}/jenkins_data" || true + sudo chown -R 999:999 "${SCRIPT_DIR}/sonarqube_data" || true +} + +# 构建和启动服务 +deploy_services() { + echo "🐳 构建并启动Jenkins服务..." + + cd "$SCRIPT_DIR" + + # 构建自定义Jenkins镜像 + docker-compose build jenkins + + # 启动所有服务 + docker-compose up -d + + echo "⏳ 等待服务启动..." + sleep 60 +} + +# 检查服务状态 +check_services() { + echo "📊 检查服务状态..." + + # 检查Jenkins + if curl -s -f http://localhost:15008 > /dev/null; then + echo "✅ Jenkins服务正常运行" + else + echo "❌ Jenkins服务启动失败" + docker logs jenkins-custom --tail 50 + exit 1 + fi + + # 检查SonarQube + if curl -s -f http://localhost:15010 > /dev/null; then + echo "✅ SonarQube服务正常运行" + else + echo "⚠️ SonarQube服务可能还在启动中..." + fi +} + +# 获取初始密码 +get_initial_password() { + echo "🔑 获取Jenkins初始密码..." + + local password_file="${SCRIPT_DIR}/jenkins_data/secrets/initialAdminPassword" + local max_attempts=30 + local attempt=1 + + while [ $attempt -le $max_attempts ]; do + if [ -f "$password_file" ]; then + echo "Jenkins初始密码:" + cat "$password_file" + break + elif docker exec jenkins-custom test -f /var/jenkins_home/secrets/initialAdminPassword 2>/dev/null; then + echo "Jenkins初始密码:" + docker exec jenkins-custom cat /var/jenkins_home/secrets/initialAdminPassword + break + else + echo "等待Jenkins生成初始密码... (尝试 $attempt/$max_attempts)" + sleep 10 + ((attempt++)) + fi + done + + if [ $attempt -gt $max_attempts ]; then + echo "⚠️ 无法获取初始密码,请手动查看容器日志" + docker logs jenkins-custom --tail 20 + fi +} + +# 显示访问信息 +show_access_info() { + echo "" + echo "🎉 Jenkins CI/CD平台部署完成!" + echo "" + echo "📋 访问信息:" + echo " 🌐 Jenkins: http://localhost:15008" + echo " 🌐 SonarQube: http://localhost:15010" + echo "" + echo "🔧 默认账号:" + echo " Jenkins: admin / (使用上面显示的初始密码)" + echo " SonarQube: admin / admin" + echo "" + echo "📁 数据目录:" + echo " Jenkins: ${SCRIPT_DIR}/jenkins_data" + echo " SonarQube: ${SCRIPT_DIR}/sonarqube_data" + echo "" + echo "🚀 快速开始:" + echo "1. 访问Jenkins并完成初始设置" + echo "2. 安装推荐插件(已预装核心插件)" + echo "3. 创建管理员用户" + echo "4. 导入示例项目: ${PROJECT_ROOT}" + echo "5. 使用 .ci-config.yml 配置项目构建" + echo "" + echo "📖 文档:" + echo " 配置指南: ${PROJECT_ROOT}/JENKINS_SETUP.md" + echo " 故障排查: ${PROJECT_ROOT}/JENKINS_TROUBLESHOOTING.md" +} + +# 创建管理脚本 +create_management_scripts() { + echo "📝 创建管理脚本..." + + # 启动脚本 + cat > "${SCRIPT_DIR}/start.sh" << 'EOF' +#!/bin/bash +cd "$(dirname "$0")" +docker-compose start +echo "✅ Jenkins服务已启动" +echo "🌐 访问地址: http://localhost:15008" +EOF + + # 停止脚本 + cat > "${SCRIPT_DIR}/stop.sh" << 'EOF' +#!/bin/bash +cd "$(dirname "$0")" +docker-compose stop +echo "✅ Jenkins服务已停止" +EOF + + # 重启脚本 + cat > "${SCRIPT_DIR}/restart.sh" << 'EOF' +#!/bin/bash +cd "$(dirname "$0")" +docker-compose restart +echo "✅ Jenkins服务已重启" +echo "🌐 访问地址: http://localhost:15008" +EOF + + # 查看日志脚本 + cat > "${SCRIPT_DIR}/logs.sh" << 'EOF' +#!/bin/bash +cd "$(dirname "$0")" +if [ "$1" = "sonar" ]; then + docker-compose logs -f sonarqube +else + docker-compose logs -f jenkins +fi +EOF + + # 备份脚本 + cat > "${SCRIPT_DIR}/backup.sh" << 'EOF' +#!/bin/bash +cd "$(dirname "$0")" +BACKUP_DIR="backup-$(date +%Y%m%d-%H%M%S)" +mkdir -p "$BACKUP_DIR" +cp -r jenkins_data "$BACKUP_DIR/" +cp -r sonarqube_data "$BACKUP_DIR/" +echo "✅ 备份完成: $BACKUP_DIR" +EOF + + # 设置执行权限 + chmod +x "${SCRIPT_DIR}"/*.sh +} + +# 主函数 +main() { + echo "企业级Jenkins CI/CD平台部署程序" + echo "=================================" + + check_docker + create_directories + deploy_services + check_services + get_initial_password + create_management_scripts + show_access_info +} + +# 执行主函数 +main "$@" diff --git a/jenkins-docker/deploy-jenkins.bat b/jenkins-docker/deploy-jenkins.bat new file mode 100644 index 0000000..9a6f596 --- /dev/null +++ b/jenkins-docker/deploy-jenkins.bat @@ -0,0 +1,72 @@ +@echo off +REM Jenkins Docker部署脚本 - Windows版本 +REM 使用方法: deploy-jenkins.bat + +echo 🚀 开始部署Jenkins with JDK 17... + +REM 检查Docker是否运行 +docker version >nul 2>&1 +if errorlevel 1 ( + echo ❌ Docker未运行,请启动Docker Desktop + pause + exit /b 1 +) + +REM 创建数据目录 +if not exist "jenkins_data" mkdir jenkins_data + +echo 📁 创建Jenkins配置目录... + +REM 拉取并运行Jenkins容器(使用官方镜像 + 安装JDK) +echo 🐳 启动Jenkins容器... + +docker run -d ^ + --name jenkins-jdk17 ^ + --restart unless-stopped ^ + -p 15008:8080 ^ + -p 50000:50000 ^ + -v jenkins_data:/var/jenkins_home ^ + -v //var/run/docker.sock:/var/run/docker.sock ^ + -e JAVA_OPTS="-Djenkins.install.runSetupWizard=false -Xmx2048m" ^ + jenkins/jenkins:lts + +echo ⏳ 等待Jenkins启动... +timeout /t 30 /nobreak + +REM 在容器中安装JDK 17和其他工具 +echo 🔧 安装JDK 17和构建工具... +docker exec -u root jenkins-jdk17 apt-get update +docker exec -u root jenkins-jdk17 apt-get install -y openjdk-17-jdk maven curl wget sshpass +docker exec -u root jenkins-jdk17 apt-get clean + +REM 安装Docker CLI +docker exec -u root jenkins-jdk17 curl -fsSL https://get.docker.com -o get-docker.sh +docker exec -u root jenkins-jdk17 sh get-docker.sh +docker exec -u root jenkins-jdk17 usermod -aG docker jenkins + +echo 📊 检查容器状态... +docker ps | findstr jenkins-jdk17 + +echo 🔑 获取Jenkins初始密码... +timeout /t 10 /nobreak +docker exec jenkins-jdk17 cat /var/jenkins_home/secrets/initialAdminPassword + +echo. +echo ✅ Jenkins部署完成! +echo 🌐 访问地址: http://localhost:15008 +echo. +echo 📋 预装环境: +echo - OpenJDK 17 +echo - Maven 3.x +echo - Docker CLI +echo - Git +echo - sshpass +echo. +echo 🔧 接下来请: +echo 1. 浏览器访问Jenkins +echo 2. 使用上面的初始密码登录 +echo 3. 安装推荐插件 +echo 4. 创建管理员用户 +echo 5. 跳过工具配置(已预装) + +pause diff --git a/jenkins-docker/deploy-jenkins.sh b/jenkins-docker/deploy-jenkins.sh new file mode 100644 index 0000000..06480ca --- /dev/null +++ b/jenkins-docker/deploy-jenkins.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +# Jenkins Docker部署脚本 - 支持JDK 17 +# 使用方法: ./deploy-jenkins.sh + +set -e + +echo "🚀 开始部署Jenkins with JDK 17..." + +# 检查Docker是否安装 +if ! command -v docker &> /dev/null; then + echo "❌ Docker未安装,请先安装Docker" + exit 1 +fi + +if ! command -v docker-compose &> /dev/null; then + echo "❌ Docker Compose未安装,请先安装Docker Compose" + exit 1 +fi + +# 创建必要的目录 +mkdir -p jenkins_data +mkdir -p jenkins-docker + +echo "📁 创建Jenkins配置目录..." + +# 设置权限 +sudo chown -R 1000:1000 jenkins_data + +echo "🐳 构建并启动Jenkins容器..." + +# 进入jenkins-docker目录 +cd jenkins-docker + +# 构建并启动服务 +docker-compose up -d --build + +echo "⏳ 等待Jenkins启动..." +sleep 30 + +# 检查容器状态 +echo "📊 检查容器状态..." +docker-compose ps + +# 获取Jenkins初始密码 +echo "🔑 获取Jenkins初始密码..." +if [ -f "../jenkins_data/secrets/initialAdminPassword" ]; then + echo "Jenkins初始密码:" + cat ../jenkins_data/secrets/initialAdminPassword +else + echo "等待Jenkins完全启动..." + sleep 60 + if [ -f "../jenkins_data/secrets/initialAdminPassword" ]; then + echo "Jenkins初始密码:" + cat ../jenkins_data/secrets/initialAdminPassword + else + echo "从容器中获取密码:" + docker exec jenkins-custom cat /var/jenkins_home/secrets/initialAdminPassword 2>/dev/null || echo "密码文件还未生成,请稍后再试" + fi +fi + +echo "" +echo "✅ Jenkins部署完成!" +echo "🌐 访问地址: http://localhost:15008" +echo "🌐 如果是远程服务器: http://YOUR_SERVER_IP:15008" +echo "" +echo "📋 配置信息:" +echo " - Jenkins端口: 15008" +echo " - SonarQube端口: 15010" +echo " - 数据目录: ./jenkins_data" +echo "" +echo "🔧 接下来请:" +echo "1. 浏览器访问Jenkins" +echo "2. 使用上面的初始密码登录" +echo "3. 安装推荐插件" +echo "4. 创建管理员用户" +echo "5. 配置项目Pipeline" + +# 显示容器日志 +echo "" +echo "📄 Jenkins启动日志 (最后20行):" +docker logs --tail 20 jenkins-custom diff --git a/jenkins-docker/docker-compose.yml b/jenkins-docker/docker-compose.yml new file mode 100644 index 0000000..09438ed --- /dev/null +++ b/jenkins-docker/docker-compose.yml @@ -0,0 +1,47 @@ +version: '3.8' + +services: + jenkins: + build: + context: . + dockerfile: Dockerfile + container_name: jenkins-custom + restart: unless-stopped + ports: + - "15008:8080" + - "50000:50000" + volumes: + - jenkins_home:/var/jenkins_home + - /var/run/docker.sock:/var/run/docker.sock + - ./jenkins_data:/var/jenkins_home/workspace + environment: + - JAVA_OPTS=-Djenkins.install.runSetupWizard=false -Xmx2048m + - JENKINS_OPTS=--httpPort=8080 + networks: + - jenkins-network + + # SonarQube服务(如果需要本地运行) + sonarqube: + image: sonarqube:community + container_name: sonarqube-custom + restart: unless-stopped + ports: + - "15010:9000" + environment: + - SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true + volumes: + - sonarqube_data:/opt/sonarqube/data + - sonarqube_extensions:/opt/sonarqube/extensions + - sonarqube_logs:/opt/sonarqube/logs + networks: + - jenkins-network + +volumes: + jenkins_home: + sonarqube_data: + sonarqube_extensions: + sonarqube_logs: + +networks: + jenkins-network: + driver: bridge diff --git a/jenkins-docker/jenkins-config/jenkins.yaml b/jenkins-docker/jenkins-config/jenkins.yaml new file mode 100644 index 0000000..a63c5e3 --- /dev/null +++ b/jenkins-docker/jenkins-config/jenkins.yaml @@ -0,0 +1,117 @@ +jenkins: + systemMessage: "企业级CI/CD平台 - 支持Java、Node.js、Python等多语言项目" + numExecutors: 4 + scmCheckoutRetryCount: 3 + mode: NORMAL + + # 安全配置 + securityRealm: + local: + allowsSignup: false + users: + - id: "admin" + password: "admin123" + name: "管理员" + email: "admin@company.com" + + # 授权策略 + authorizationStrategy: + roleBased: + roles: + global: + - name: "admin" + description: "系统管理员" + permissions: + - "Overall/Administer" + assignments: + - "admin" + - name: "developer" + description: "开发人员" + permissions: + - "Overall/Read" + - "Job/Build" + - "Job/Cancel" + - "Job/Read" + - "Job/Workspace" + - "Run/Replay" + - "Run/Update" + assignments: + - "authenticated" + +# 全局工具配置 +tool: + # JDK配置 + jdk: + installations: + - name: "JDK-17" + home: "/usr/lib/jvm/java-17-openjdk-amd64" + properties: + - installSource: + installers: + - command: + command: "" + + # Maven配置 + maven: + installations: + - name: "Maven-3.9" + home: "/usr/share/maven" + properties: + - installSource: + installers: + - maven: + id: "3.9.6" + + # Git配置 + git: + installations: + - name: "Default" + home: "git" + +# SonarQube配置 +unclassified: + sonarGlobalConfiguration: + installations: + - name: "SonarQube" + serverUrl: "http://116.62.163.84:15010" + credentialsId: "sonar-token" + + # 邮件配置 + mailer: + smtpHost: "smtp.company.com" + smtpPort: 587 + charset: "UTF-8" + + # 全局库配置 + globalLibraries: + libraries: + - name: "ci-cd-shared-library" + defaultVersion: "main" + retriever: + modernSCM: + scm: + git: + remote: "http://116.62.163.84:15006/shared/jenkins-shared-library.git" + +# 凭据配置 +credentials: + system: + domainCredentials: + - credentials: + - usernamePassword: + scope: GLOBAL + id: "git-credentials" + username: "wangtianqi" + password: "your-git-password" + description: "Git仓库凭据" + - usernamePassword: + scope: GLOBAL + id: "deploy-server-ssh" + username: "root" + password: "your-server-password" + description: "部署服务器SSH凭据" + - string: + scope: GLOBAL + id: "sonar-token" + secret: "squ_7e4217cabd0faae6f3b8ee359b3b8e2ac52eb69a" + description: "SonarQube访问令牌" diff --git a/jenkins-docker/pipeline-templates/universal-pipeline.groovy b/jenkins-docker/pipeline-templates/universal-pipeline.groovy new file mode 100644 index 0000000..2d4283b --- /dev/null +++ b/jenkins-docker/pipeline-templates/universal-pipeline.groovy @@ -0,0 +1,251 @@ +/** + * 企业级通用CI/CD Pipeline模板 + * 支持多种项目类型:Java Maven/Gradle、Node.js、Python等 + * + * 使用方法: + * 1. 在项目根目录创建 .ci-config.yml 文件 + * 2. 配置项目类型和构建参数 + * 3. Jenkinsfile 中调用此模板 + */ + +@Library('ci-cd-shared-library') _ + +pipeline { + agent any + + options { + buildDiscarder(logRotator(numToKeepStr: '10')) + timeout(time: 30, unit: 'MINUTES') + timestamps() + skipDefaultCheckout() + } + + environment { + // 动态从配置文件加载 + CI_CONFIG = readFile('.ci-config.yml') + } + + stages { + stage('初始化') { + steps { + script { + // 读取项目配置 + def config = readYaml text: env.CI_CONFIG + env.PROJECT_TYPE = config.project?.type ?: 'java-maven' + env.PROJECT_NAME = config.project?.name ?: env.JOB_NAME + env.DEPLOY_TARGET = config.deploy?.target ?: 'test' + + echo "🚀 开始构建项目: ${env.PROJECT_NAME}" + echo "📋 项目类型: ${env.PROJECT_TYPE}" + echo "🎯 部署目标: ${env.DEPLOY_TARGET}" + } + + // 检出代码 + checkout scm + + script { + env.GIT_COMMIT_SHORT = sh( + script: "git rev-parse --short HEAD", + returnStdout: true + ).trim() + } + } + } + + stage('环境检测') { + steps { + script { + // 调用共享库中的环境检测方法 + detectBuildEnvironment() + } + } + } + + stage('代码分析') { + parallel { + stage('编译') { + steps { + script { + // 根据项目类型选择构建方法 + switch(env.PROJECT_TYPE) { + case 'java-maven': + buildJavaMaven() + break + case 'java-gradle': + buildJavaGradle() + break + case 'nodejs': + buildNodejs() + break + case 'python': + buildPython() + break + default: + error "不支持的项目类型: ${env.PROJECT_TYPE}" + } + } + } + } + + stage('代码质量检查') { + steps { + script { + // 执行代码质量检查 + runCodeQualityCheck() + } + } + } + } + } + + stage('测试') { + parallel { + stage('单元测试') { + steps { + script { + runUnitTests() + } + } + post { + always { + publishTestResults() + publishCoverageReport() + } + } + } + + stage('集成测试') { + when { + expression { + return fileExists('src/test/java/integration') || + fileExists('tests/integration') + } + } + steps { + script { + runIntegrationTests() + } + } + } + } + } + + stage('SonarQube分析') { + steps { + script { + runSonarQubeAnalysis() + } + } + } + + stage('构建制品') { + parallel { + stage('打包应用') { + steps { + script { + buildArtifacts() + } + } + post { + success { + archiveArtifacts artifacts: getArtifactPattern(), fingerprint: true + } + } + } + + stage('构建镜像') { + when { + expression { return fileExists('Dockerfile') } + } + steps { + script { + buildDockerImage() + } + } + } + } + } + + stage('安全扫描') { + parallel { + stage('依赖扫描') { + steps { + script { + runDependencyCheck() + } + } + } + + stage('镜像安全扫描') { + when { + expression { return fileExists('Dockerfile') } + } + steps { + script { + runImageSecurityScan() + } + } + } + } + } + + stage('部署') { + when { + anyOf { + branch 'main' + branch 'develop' + branch 'release/*' + } + } + steps { + script { + // 部署到目标环境 + deployToEnvironment(env.DEPLOY_TARGET) + } + } + } + + stage('部署验证') { + when { + anyOf { + branch 'main' + branch 'develop' + branch 'release/*' + } + } + steps { + script { + // 执行部署后验证 + runDeploymentValidation() + } + } + } + } + + post { + always { + script { + // 清理工作空间 + cleanupWorkspace() + } + } + + success { + script { + sendNotification('success') + } + } + + failure { + script { + sendNotification('failure') + } + } + + unstable { + script { + sendNotification('unstable') + } + } + } +}