feat: 完善Jenkins流水线配置
主要更新: - 使用SSH私钥认证替代用户名密码认证 - 配置deploy-server-ssh-key凭据ID - 修复Jenkinsfile格式和缩进问题 - 添加SSH配置指南和企业级部署文档 技术改进: - 使用sshagent进行安全的SSH连接 - 移除sshpass依赖,提升安全性 - 统一使用root@116.62.163.84进行部署 - 优化Docker镜像传输和部署流程 新增文档: - SSH_CONFIG_GUIDE.md - SSH私钥配置指南 - ENTERPRISE_JENKINS_GUIDE.md - 企业级Jenkins部署 - jenkins-docker/ - Jenkins Docker化部署方案
This commit is contained in:
parent
0725abdcb4
commit
7b8bd55554
144
.ci-config.yml
Normal file
144
.ci-config.yml
Normal file
@ -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
|
268
ENTERPRISE_JENKINS_GUIDE.md
Normal file
268
ENTERPRISE_JENKINS_GUIDE.md
Normal file
@ -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编写。
|
29
Jenkinsfile
vendored
29
Jenkinsfile
vendored
@ -11,17 +11,18 @@ pipeline {
|
|||||||
// 使用系统默认或Jenkins节点上已安装的JDK
|
// 使用系统默认或Jenkins节点上已安装的JDK
|
||||||
// 不再强制指定JAVA_HOME,让Jenkins自动检测
|
// 不再强制指定JAVA_HOME,让Jenkins自动检测
|
||||||
|
|
||||||
// 目标服务器配置
|
// 目标服务器配置 DEPLOY_SERVER = '116.62.163.84'
|
||||||
DEPLOY_SERVER = '116.62.163.84'
|
|
||||||
|
|
||||||
// Docker相关环境变量
|
// Docker相关环境变量
|
||||||
IMAGE_NAME = 'jenkins-demo'
|
IMAGE_NAME = 'jenkins-demo'
|
||||||
IMAGE_TAG = "${BUILD_NUMBER}"
|
IMAGE_TAG = "${BUILD_NUMBER}"
|
||||||
|
|
||||||
// SonarQube配置
|
// SonarQube配置
|
||||||
SONAR_HOST_URL = 'http://116.62.163.84:15010'
|
SONAR_HOST_URL = 'http://116.62.163.84:15010'
|
||||||
SONAR_PROJECT_KEY = 'jenkins-demo'
|
SONAR_PROJECT_KEY = 'jenkins-demo'
|
||||||
SONAR_TOKEN = 'squ_7e4217cabd0faae6f3b8ee359b3b8e2ac52eb69a'
|
SONAR_TOKEN = 'squ_7e4217cabd0faae6f3b8ee359b3b8e2ac52eb69a'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用Jenkins中配置的工具(自动安装)
|
// 使用Jenkins中配置的工具(自动安装)
|
||||||
tools {
|
tools {
|
||||||
maven 'Maven-3.9.6' // 使用您在Jenkins中配置的Maven名称
|
maven 'Maven-3.9.6' // 使用您在Jenkins中配置的Maven名称
|
||||||
@ -164,22 +165,16 @@ pipeline {
|
|||||||
echo '📤 传输Docker镜像到目标服务器...'
|
echo '📤 传输Docker镜像到目标服务器...'
|
||||||
script {
|
script {
|
||||||
// 将Docker镜像保存为tar文件并传输到目标服务器
|
// 将Docker镜像保存为tar文件并传输到目标服务器
|
||||||
withCredentials([usernamePassword(credentialsId: 'deploy-server-ssh', usernameVariable: 'SSH_USER', passwordVariable: 'SSH_PASS')]) {
|
sshagent(['deploy-server-ssh-key']) {
|
||||||
sh '''
|
sh '''
|
||||||
# 保存Docker镜像为tar文件
|
# 保存Docker镜像为tar文件
|
||||||
docker save ${IMAGE_NAME}:${IMAGE_TAG} -o ${IMAGE_NAME}-${IMAGE_TAG}.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镜像
|
||||||
docker load -i /tmp/${IMAGE_NAME}-${IMAGE_TAG}.tar
|
docker load -i /tmp/${IMAGE_NAME}-${IMAGE_TAG}.tar
|
||||||
|
|
||||||
@ -212,9 +207,9 @@ EOF
|
|||||||
echo '🚀 部署到测试环境...'
|
echo '🚀 部署到测试环境...'
|
||||||
script {
|
script {
|
||||||
// 部署到测试服务器
|
// 部署到测试服务器
|
||||||
withCredentials([usernamePassword(credentialsId: 'deploy-server-ssh', usernameVariable: 'SSH_USER', passwordVariable: 'SSH_PASS')]) {
|
sshagent(['deploy-server-ssh-key']) {
|
||||||
sh '''
|
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 stop jenkins-demo-test || true
|
||||||
docker rm jenkins-demo-test || true
|
docker rm jenkins-demo-test || true
|
||||||
@ -249,9 +244,9 @@ EOF
|
|||||||
parameters: [choice(name: 'DEPLOY_ENV', choices: ['prod'], description: '选择部署环境')]
|
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 '''
|
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
|
docker tag ${IMAGE_NAME}:latest ${IMAGE_NAME}:backup-$(date +%Y%m%d-%H%M%S) || true
|
||||||
|
|
||||||
|
9
Jenkinsfile.template
Normal file
9
Jenkinsfile.template
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* 简化版Jenkinsfile
|
||||||
|
* 所有复杂逻辑都在共享库和模板中处理
|
||||||
|
* 项目只需要维护 .ci-config.yml 配置文件
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 加载通用Pipeline模板
|
||||||
|
def pipelineTemplate = libraryResource 'templates/universal-pipeline.groovy'
|
||||||
|
evaluate(pipelineTemplate)
|
68
SSH_CONFIG_GUIDE.md
Normal file
68
SSH_CONFIG_GUIDE.md
Normal file
@ -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(默认,除非有变更)
|
102
jenkins-docker/Dockerfile
Normal file
102
jenkins-docker/Dockerfile
Normal file
@ -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 '<?xml version="1.0" encoding="UTF-8"?>' > /root/.m2/settings.xml && \
|
||||||
|
echo '<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"' >> /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 ' <mirrors>' >> /root/.m2/settings.xml && \
|
||||||
|
echo ' <mirror>' >> /root/.m2/settings.xml && \
|
||||||
|
echo ' <id>aliyunmaven</id>' >> /root/.m2/settings.xml && \
|
||||||
|
echo ' <mirrorOf>*</mirrorOf>' >> /root/.m2/settings.xml && \
|
||||||
|
echo ' <name>阿里云公共仓库</name>' >> /root/.m2/settings.xml && \
|
||||||
|
echo ' <url>https://maven.aliyun.com/repository/public</url>' >> /root/.m2/settings.xml && \
|
||||||
|
echo ' </mirror>' >> /root/.m2/settings.xml && \
|
||||||
|
echo ' </mirrors>' >> /root/.m2/settings.xml && \
|
||||||
|
echo '</settings>' >> /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
|
211
jenkins-docker/deploy-enterprise.sh
Normal file
211
jenkins-docker/deploy-enterprise.sh
Normal file
@ -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 "$@"
|
72
jenkins-docker/deploy-jenkins.bat
Normal file
72
jenkins-docker/deploy-jenkins.bat
Normal file
@ -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
|
82
jenkins-docker/deploy-jenkins.sh
Normal file
82
jenkins-docker/deploy-jenkins.sh
Normal file
@ -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
|
47
jenkins-docker/docker-compose.yml
Normal file
47
jenkins-docker/docker-compose.yml
Normal file
@ -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
|
117
jenkins-docker/jenkins-config/jenkins.yaml
Normal file
117
jenkins-docker/jenkins-config/jenkins.yaml
Normal file
@ -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访问令牌"
|
251
jenkins-docker/pipeline-templates/universal-pipeline.groovy
Normal file
251
jenkins-docker/pipeline-templates/universal-pipeline.groovy
Normal file
@ -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')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user