jenkins搭建docker启动

介绍:本文介绍使用docker命令启动jenkins,并搭建服务自动部署流水线

1. docker启动jenkins.

我的服务器上安装的是jdk17,所以我指定了镜像版本,启动的时候必须指定配置-e JAVA_OPTS="-Djenkins.update.center=https://mirrors.huaweicloud.com/jenkins/update-center.json" ,主要是为了启动完成,安装插件的时候速度快一些,默认的是https://updates.jenkins-zh.cn/update-center.json,安装插件的时候会很慢。

复制代码
docker run -d \
  --name jenkins \
  --restart=unless-stopped \
  -p 19009:8080 \
  -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home \
  -e JAVA_OPTS="-Djenkins.update.center=https://mirrors.huaweicloud.com/jenkins/update-center.json" \
  -e JAVA_OPTS="-Dhudson.model.UpdateCenter.connectionCheckUrl=https://www.baidu.com" \
  jenkins/jenkins:2.541.3-lts-jdk17

2.访问ip:端口

进入jenkins页面要求输入密码,这里运行命令

docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

会展示一个字符串,例如:116125d432e24411afa2f1a906946485 复制进去点击继续

3.安装插件

安装默认的插件,不要跳过,否则还得自己一个一个的安装,可能会漏装插件,导致搭建自动部署的时候报错

4.设置账号密码

插件安装完成之后,我设置了账号密码,但是在另一个浏览器登录的时候显示密码错误,所以在原来的浏览器中又找到设置---user---account ----security---修改了账户密码,这样就能登录了

5.安装ssh插件

命令

docker exec -u root jenkins bash -c 'apt-get update && apt-get install -y sshpass openssh-client

6. 配置git凭据和其他服务器的凭据

凭据创建好之后

7全局配置jdk和maven

由于我的jenkins默认的是jdk17,项目使用的是jdk21 ,所以还需要安装一个jdk21在容器中

复制代码
# 进入容器(用户一般是 jenkins,装软件用 root)
docker exec -u root -it jenkins bash

mkdir -p /var/jenkins_home/tools
cd /var/jenkins_home/tools


# 下载 Temurin 21(若清华慢可换官方或其它镜像)
curl -fL -o jdk21.tar.gz \
  "https://mirrors.tuna.tsinghua.edu.cn/Adoptium/21/jdk/x64/linux/OpenJDK21U-jdk_x64_linux_hotspot_21.0.6_7.tar.gz"

tar -xzf jdk21.tar.gz
mv jdk-21.0.12+8  jdk-21


# 建固定软链,方便配置
ln -sfn "$(ls -d jdk-21* | head -1)" jdk-21


/var/jenkins_home/tools/jdk-21/bin/java -version
# 应显示 21.x

8.新建流水线任务

点击左上角那个jenkins返回主页面,新建一个任务

2填写描述

脚本代码

复制代码
/**
 * Spring Boot 宿主机部署 Pipeline(Jenkins 跑在 Docker 内)
 *
 * 前置条件:
 * 1) Jenkins 容器能访问宿主机 SSH(推荐),启动示例:
 *    docker run -d --name jenkins --restart=unless-stopped \
 *      -p 8080:8080 -p 50000:50000 \
 *      -v jenkins_home:/var/jenkins_home \
 *      -v /var/run/docker.sock:/var/run/docker.sock \
 *      jenkins/jenkins:2.541.3-lts-jdk17
 * 2) 本项目编译需要 JDK21(pom 中 release=21)。Jenkins 控制器可以是 jdk17 镜像,
 *    但构建必须用 JDK21:Manage Jenkins → Tools 配置 Name=jdk21 的 JDK。
 * 3) 宿主机运行 jar 也需要 JDK21;openssh-server;部署目录已放 deploy-on-host.sh
 * 4) 插件:Pipeline、Git、SSH Agent;Tools 中 Maven Name=maven
 * 5) 凭据:git-test、host-ssh
 *
 * 报错 release version 21 not supported = 构建仍在用 JDK17,按下面配 jdk21。
 */
pipeline {
    agent any
    tools {
        jdk   'JDK21'
        maven 'maven'
    }
    options {
        timestamps()
        disableConcurrentBuilds()
        buildDiscarder(logRotator(numToKeepStr: '20'))
    }

    parameters {
        string(name: 'GIT_BRANCH', defaultValue: 'develop', description: 'Git 分支')
        booleanParam(name: 'SKIP_TESTS', defaultValue: true, description: '是否跳过测试')
    }

    environment {
        // ==== 按实际项目修改 ====
        APP_NAME           = 'appname'
        GIT_URL            = 'https://替换你自己的地址.git'
        GIT_CREDENTIALS_ID = '替换自己的凭据git-test'  //cred
        // 宿主机 SSH:从 Jenkins 容器访问宿主机网关,常见为 172.17.0.1
        // 也可用宿主机内网 IP / 配置的 host 名
        HOST_IP            = '项目启动的服务ip'
        HOST_USER          = 'root'
        HOST_SSH_CRED_ID   = '替换这里是配置的凭据host-ssh'
        HOST_DEPLOY_DIR    = '替换发布的文件夹地址/etc/apps/'
        JAR_NAME           = '替换.jar'          // 部署后的统一文件名
        // Maven 坐标打包名不确定时,用下面通配;最终仍会 scp 成 JAR_NAME
        JAVA_OPTS          = '-Xms256m -Xmx512m'
        SPRING_PROFILE     = 'prod'
        APP_PORT           = '替换端口'
        // ========================

        WORK_JAR_GLOB      = 'target/*.jar'
    }
 stages {
        
stage('Checkout') {
            steps {
                cleanWs()
                git branch: "${params.GIT_BRANCH}",
                    credentialsId: "${env.GIT_CREDENTIALS_ID}",
                    url: "${env.GIT_URL}"
            }
        }

        stage('Maven Build') {
            steps {
                script {
                    def skip = params.SKIP_TESTS ? '-DskipTests' : ''
                    // tools 会注入 JAVA_HOME;再强制校验必须是 21
                    sh """
                        set -e
                        echo "JAVA_HOME=\$JAVA_HOME"
                        java -version
                        javac -version
                        # 确认 compiler 支持 --release 21
                        javac --release 21 -version
                        mvn -version
                        mvn -B -U clean package ${skip}
                        ls -lh target/*.jar
                    """
                }
            }
        }
        
        stage('Pick Artifact') {
            steps {
                script {
                    def jars = sh(
                        script: '''
                            ls -1 target/*.jar 2>/dev/null \
                              | grep -v '\\.original$' \
                              | grep -v sources \
                              | grep -v javadoc \
                              || true
                        ''',
                        returnStdout: true
                    ).trim().split('\n').findAll { it?.trim() }
                    if (jars.isEmpty()) {
                        error('未找到可部署的 jar,请检查 Maven packaging')
                    }
                    env.BUILT_JAR = jars[0]
                    echo "构建产物: ${env.BUILT_JAR}"
                }
            }
        }
        stage('Deploy to Host') {
            steps {
                // host-ssh 是 Username with password,不能用 sshUserPrivateKey
                withCredentials([usernamePassword(
                    credentialsId: env.HOST_SSH_CRED_ID,
                    usernameVariable: 'SSH_USER',
                    passwordVariable: 'SSH_PASS'
                )]) {
                    sh """
                        set -e
                        if ! command -v sshpass >/dev/null 2>&1; then
                          echo "Jenkins 容器缺少 sshpass,请执行:"
                          echo "  docker exec -u root jenkins bash -c 'apt-get update && apt-get install -y sshpass openssh-client'"
                          exit 1
                        fi
                        export SSHPASS="\$SSH_PASS"
                        SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
                        REMOTE="\${SSH_USER}@${HOST_IP}"

                        # 1) 进入部署目录,删除旧 jar
                        sshpass -e ssh \$SSH_OPTS \$REMOTE "mkdir -p '${HOST_DEPLOY_DIR}' && cd '${HOST_DEPLOY_DIR}' && rm -f '${JAR_NAME}' *.jar"

                        # 2) 把构建产物传到 HOST_DEPLOY_DIR,统一命名为 JAR_NAME
                        sshpass -e scp \$SSH_OPTS "${env.BUILT_JAR}" "\$REMOTE:${HOST_DEPLOY_DIR}/${JAR_NAME}"

                        # 3) 启动服务
                        sshpass -e ssh \$SSH_OPTS \$REMOTE "cd '${HOST_DEPLOY_DIR}' && bash start.sh"
                    """
                }
            }
        }

        stage('Health Check') {
            steps {
                withCredentials([usernamePassword(
                    credentialsId: env.HOST_SSH_CRED_ID,
                    usernameVariable: 'SSH_USER',
                    passwordVariable: 'SSH_PASS'
                )]) {
                    sh """
                        set -e
                        export SSHPASS="\$SSH_PASS"
                        SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
                        REMOTE="\${SSH_USER}@${HOST_IP}"
                        for i in 1 2 3 4 5 6 7 8 9 10; do
                          if sshpass -e ssh \$SSH_OPTS \$REMOTE \
                            "curl -fsS http://127.0.0.1:${APP_PORT}/actuator/health \
                             || curl -fsS -o /dev/null -w '%{http_code}' http://127.0.0.1:${APP_PORT}/ | grep -E '200|302|401'"; then
                            echo "健康检查通过"
                            exit 0
                          fi
                          echo "等待服务启动... (\$i/10)"
                          sleep 3
                        done
                        echo "健康检查失败,请查看宿主机日志: ${HOST_DEPLOY_DIR}/app.log"
                        exit 1
                    """
                }
            }
        }
    }

    post {
        success {
            echo "部署成功: ${APP_NAME} -> ${HOST_IP}:${APP_PORT}"
        }
        failure {
            echo "部署失败,请检查构建日志与宿主机 ${HOST_DEPLOY_DIR}/app.log"
        }
        always {
            archiveArtifacts artifacts: 'target/*.jar', fingerprint: true, allowEmptyArchive: true
        }
    }
}
相关推荐
snow@li1 小时前
服务器运维:K3S 下 Jenkins ↔ GitLab 的 CI/CD 闭环 / 访问成功
运维·gitlab·jenkins
qq_349447951 天前
Jenkins如何创建一个只能查看固定项目的账号
运维·jenkins
qq_349447952 天前
阿里云centos7.9系统安装jenkins
服务器·阿里云·jenkins
qq_349447953 天前
jenkin节点创建
jenkins
飞翔的熊blabla5 天前
# Webpack 5 + Jenkins 持久化缓存实战:前端构建从 288 秒降到 30 秒>
前端·webpack·jenkins
海兰6 天前
Elasticsearch ES|QL:让全文本搜索无处不在
大数据·elasticsearch·jenkins
IT界的老黄牛6 天前
Jenkins 监控一条龙:接入、看板 9964、11 条告警规则直接抄走
jenkins·grafana·prometheus·监控·ci-cd·告警规则
小袁拒绝摆烂7 天前
Jenkins部署经验
运维·jenkins
IT界的老黄牛7 天前
Jenkins 构建卡了 23 天,abort 按钮点了没用
jenkins·maven·prometheus·告警·排查·ci-cd