砍材农夫砍材农夫
  • 微信记账小程序
  • java
  • redis
  • mysql
  • 场景类
  • 框架类
  • vuepress搭建
  • hexo搭建
  • 云图
  • llm wiki

    • 基于karpathy
    • gradle
  • 常用工具

    • git
    • gradle
    • Zadig
    • it-tools
    • 开源推荐
    • curl
  • 大前端

    • 环境配置
    • 微信生态
    • 正则
    • 全栈技能
  • java圈

    • java基础
    • jdk体系
    • jvm
    • spring框架
    • 分库分表
    • zookeeper
  • python技能

    • python编程
    • python数据
  • 算法

    • 算法
  • 网关

    • spring_cloud_gateway
    • openresty
  • 高可用

    • 秒杀
    • 分布式
    • 缓存一致
  • MQ

    • MQ
    • rabbitMQ
    • rocketMQ
    • kafka
  • 其它

    • 设计模式
    • 领域驱动(ddd)
  • 关系型数据库

    • mysql5.0
    • mysql8.0
  • 非关系型数据库

    • redis
    • mongoDB
  • 分布式/其他

    • ShardingSphere
    • 区块链
  • 向量数据库

    • M3E
    • OPEN AI
  • Jmeter
  • fiddler
  • wireshark
  • AI入门
  • AI大模型
  • AI插件
  • AI集成框架
  • 相关算法
  • AI训练师
  • 量化交易
  • AIoT
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 相关运营
  • devops
  • 元宇宙
  • 区块链
  • 物联网
  • webrtc
  • web3.0
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 中考
  • 投资
  • 保险
  • 思
  • 微信记账小程序
  • java
  • redis
  • mysql
  • 场景类
  • 框架类
  • vuepress搭建
  • hexo搭建
  • 云图
  • llm wiki

    • 基于karpathy
    • gradle
  • 常用工具

    • git
    • gradle
    • Zadig
    • it-tools
    • 开源推荐
    • curl
  • 大前端

    • 环境配置
    • 微信生态
    • 正则
    • 全栈技能
  • java圈

    • java基础
    • jdk体系
    • jvm
    • spring框架
    • 分库分表
    • zookeeper
  • python技能

    • python编程
    • python数据
  • 算法

    • 算法
  • 网关

    • spring_cloud_gateway
    • openresty
  • 高可用

    • 秒杀
    • 分布式
    • 缓存一致
  • MQ

    • MQ
    • rabbitMQ
    • rocketMQ
    • kafka
  • 其它

    • 设计模式
    • 领域驱动(ddd)
  • 关系型数据库

    • mysql5.0
    • mysql8.0
  • 非关系型数据库

    • redis
    • mongoDB
  • 分布式/其他

    • ShardingSphere
    • 区块链
  • 向量数据库

    • M3E
    • OPEN AI
  • Jmeter
  • fiddler
  • wireshark
  • AI入门
  • AI大模型
  • AI插件
  • AI集成框架
  • 相关算法
  • AI训练师
  • 量化交易
  • AIoT
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 相关运营
  • devops
  • 元宇宙
  • 区块链
  • 物联网
  • webrtc
  • web3.0
  • gitee
  • github
  • infoq
  • osc
  • 砍材工具
  • 关于
  • 中考
  • 投资
  • 保险
  • 思
  • nginx

    • nginx日常

      • 概念
      • 常用命令
      • nginx安装和部署
    • nginx实战

      • 基本配置拆解
      • 配置https证书
      • nginx负载配置
    • webUI

      • nginxWebUI
  • linuxs

    • 基础

      • 常用命令
      • grep
      • 防火墙
      • 基础常用命令
      • linux基础常用命令2
      • 配置应用自动启动
      • 自动同步北京时间
      • 防火墙操作
      • ifconfig无ip
      • Rocky-8无网络和局域网无法访问
    • 高级

      • 常用命令
      • vm虚拟机磁盘扩容
      • jdk安装
      • centos7 不显示IP
      • linux分析问题常用命令
      • linux任务管理
      • 权限控制
      • 记录用户操作日志
      • 日常分析问题命令介绍
      • 网络配置
      • cached过高问题
      • 找回删除文件
      • cpu负载突然升高
      • 磁盘爆满查找大文件
      • CentOS7系统配置国内yum源和epel源
    • vi

    • curl

  • docker

    • 基础
      • 安装和配置

        • window相关安装和配置
        • window基础简单操作
        • linux安装
        • 相关概念
      • 相关命令

        • 相关命令
        • docker镜像相关命令
      • 安装实例

        • 安装elasticsearch
        • docker其他常见快速部署
        • docker搭建mysql
        • docker备份mysql
        • docker更改mysql配置
        • docker搭建nexus
      • 其他

        • 镜像的迁移和备份
        • 网络
        • 常见错误集
        • docker部署hdfs
        • docker容器时间和本地时间不一致
        • docker批量操作
    • 日常运维

      • docker实例内文件下载
      • docker仓库搭建(Nexus)
      • docker仓库搭建(Hub)
    • docker-file

      • dockerfile入门
      • dockerfile(java应用)
    • docker-compose

      • docker-compose意义
  • k8s

    • 首页
      • window相关安装和配置
      • window基础简单操作
  • haproxy

    • haproxy部署实战

      • haproxy部署介绍
      • haproxy部署实战
      • haproxy案例分析
  • jenkins

    • 环境部署搭建
    • 自由风格构建应用发布
    • 获取远程git项目|分支选择
    • pipeline构建应用
    • pipeline结合docker构建应用
    • 权限管理
    • web项目构建
    • 集成maven获取远程项目
    • 视图细粒度权限管理
    • 其他日常操作案例
    • 版本升级或重装备份问题
    • 多模块关联关闭
  • prometheus

    • 首页
      • window相关安装和配置
      • window基础简单操作
  • gitlab

    • 首页
      • window相关安装和配置
      • window基础简单操作
  • maven

    • 首页
      • window相关安装和配置
      • window基础简单操作
  • elk

    • openobserve

      • docker部署openobserve
      • 采集器fluent
      • openobserve日常管理使用
  • 运维|devops|Jenkins|pipeline结合docker构建应用
    • 部署前置条件
      • 检查当前 Jenkins 容器启动参数
      • 停止并删除当前容器
      • 使用新命令启动容器(新增挂载 /usr/bin/docker)
    • 其他前置条件
      • 配置Nexus 仓库凭证
      • Docker Pipeline 插件安装
      • nexus 允许匿名推送镜像
      • 相关权限开通
      • 目标应用服务器
    • 相关脚本
      • docker
      • jenkins
    • 部署结果

运维|devops|Jenkins|pipeline结合docker构建应用

基于 jenkins Version 2.541.3 Pipeline 实操案例

部署前置条件

Jenkins容器是否挂载宿主机Docker,本案例都是基于docker部署的Jenkins

检查当前 Jenkins 容器启动参数

docker inspect jenkins | grep -A 10 "Mounts"

停止并删除当前容器

docker stop jenkins
docker rm jenkins

使用新命令启动容器(新增挂载 /usr/bin/docker)

docker run -d \
  --name jenkins \
  --restart always \
  -p 8080:8080 \
  -p 50000:50000 \
  -v /data/jenkins:/var/jenkins_home \
  -v /etc/localtime:/etc/localtime:ro \
  -v /usr/local/apache-maven-3.9.6:/usr/local/maven \
  -v /usr/local/jdk-21.0.11:/usr/local/jdk21 \
  -v /data/maven_repo:/root/.m2/repository \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /usr/bin/docker:/usr/bin/docker \
  -v /etc/docker/daemon.json:/etc/docker/daemon.json \
  jenkins/jenkins:lts-jdk17  

其他前置条件

配置Nexus 仓库凭证

img

Docker Pipeline 插件安装

img

nexus 允许匿名推送镜像

img

相关权限开通

  • 临时开通(docker所在服务器和目标应用服务器)
sudo chmod 666 /var/run/docker.sock
  • 永久开通

编辑 /etc/systemd/system/docker.service.d/override.conf(如果不存在则创建)

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock --group=docker --exec-opt native.cgroupdriver=systemd
sudo systemctl daemon-reload
sudo systemctl restart docker

目标应用服务器

  • sudo vi /etc/docker/daemon.json
{
  "registry-mirrors": [
    "https://docker.xuanyuan.me",
    "https://docker.1ms.run",
    "https://docker.m.daocloud.io"
  ],
  "insecure-registries": ["192.168.0.88:8881"]
}
  • 重启
sudo systemctl daemon-reload
sudo systemctl restart docker
  • 检查
docker info | grep -A 2 "Insecure Registries"
  • 默认登录下(保证有登录信息)
docker login 192.168.0.88:8881

相关脚本

docker

# 使用轻量级 JRE 镜像(基于 Alpine,体积更小)
FROM eclipse-temurin:21-jre-alpine

LABEL maintainer="your-email@example.com"

WORKDIR /app

# 复制 JAR 包(使用通配符,适应版本变化)
COPY target/*.jar app.jar

# 暴露应用端口
EXPOSE 6086

# 设置 JVM 参数(可通过环境变量覆盖)
ENV JAVA_OPTS="-Xms256m -Xmx512m"

# 健康检查(需应用暴露 /actuator/health 端点)
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:6086/actuator/health || exit 1

# 启动命令(支持传入 JAVA_OPTS)
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

jenkins

pipeline {
    agent any

    options {
        disableConcurrentBuilds()
        timeout(time: 20, unit: 'MINUTES')
        timestamps()
        buildDiscarder(logRotator(numToKeepStr: '10'))
    }

    parameters {
        booleanParam(
            name: 'AUTO_DEPLOY',
            defaultValue: false,
            description: '构建完成自动推送镜像并重启远程服务'
        )
        string(
            name: 'IMAGE_TAG',
            defaultValue: '',
            description: '镜像标签,留空则使用 Jenkins 构建号'
        )
    }

    environment {
        SERVICE_DIR       = 'app'
        SERVICE_NAME      = 'app'
        JAR_VERSION       = '1.0.0-SNAPSHOT'
        JAR_FILE          = "${SERVICE_NAME}-${JAR_VERSION}.jar"
        LOCAL_JAR_PATH    = "${SERVICE_DIR}/target/${JAR_FILE}"

        JAVA_HOME         = '/usr/local/jdk21'
        M2_HOME           = '/usr/local/maven'

        REGISTRY          = '192.168.0.20:8881'
        IMAGE_NAME        = "${REGISTRY}/${SERVICE_NAME}"
        IMAGE_TAG         = "${params.IMAGE_TAG ?: env.BUILD_ID}"

        REMOTE_HOST       = '192.168.0.19'
        REMOTE_USER       = 'test'
        SSH_CREDENTIALS_ID = 'test'
        CONTAINER_NAME    = "${SERVICE_NAME}"
        HOST_PORT         = '6086'
        CONTAINER_PORT    = '6086'
        CONFIG_HOST_PATH  = '/data/test/config'
        CONFIG_CONTAINER_PATH = '/data/test/config'
    }

    stages {
        stage('1. 环境信息 & Git提交日志打印') {
            steps {
                sh '''#!/bin/bash
                    echo "==================== Git 最新提交信息 ===================="
                    echo "短提交号: $(git rev-parse --short HEAD)"
                    echo "完整commit: $(git rev-parse HEAD)"
                    echo "提交人姓名: $(git log -1 --pretty=%an)"
                    echo "提交备注:"
                    git log -1 --pretty=%B
                    echo "=========================================================="
                '''
                echo "【构建信息】服务名:${env.SERVICE_NAME}|镜像:${env.IMAGE_NAME}:${env.IMAGE_TAG}"
                echo "本地JAR路径:${env.LOCAL_JAR_PATH}"
                echo "远端主机:${env.REMOTE_HOST}"
            }
        }

        stage('2. Maven编译打包') {
            steps {
                sh '''#!/bin/bash
                    test -d ${JAVA_HOME} || { echo "❌ JAVA_HOME目录不存在"; exit 1; }
                    test -d ${M2_HOME} || { echo "❌ M2_HOME目录不存在"; exit 1; }
                    ${JAVA_HOME}/bin/java -version
                    ${M2_HOME}/bin/mvn -v
                    cd ${SERVICE_DIR}
                    ${M2_HOME}/bin/mvn clean package -DskipTests
                '''
            }
        }

        stage('3. 归档构建产物(可选)') {
            steps {
                archiveArtifacts artifacts: "${env.LOCAL_JAR_PATH}", fingerprint: true, onlyIfSuccessful: true
            }
        }

        stage('4. 构建并推送 Docker 镜像') {
            steps {
                script {
                    docker.withRegistry("http://${env.REGISTRY}", 'nexus-credentials') {
                        def image = docker.build("${env.IMAGE_NAME}:${env.IMAGE_TAG}", "-f ${env.SERVICE_DIR}/Dockerfile ${env.SERVICE_DIR}")
                        image.push()
                        echo "✅ 镜像推送成功: ${env.IMAGE_NAME}:${env.IMAGE_TAG}"
                    }
                }
            }
        }

        stage('5. 远程发布部署') {
            when {
                expression { params.AUTO_DEPLOY }
            }
            steps {
                echo "开始远程部署新镜像到 ${env.REMOTE_HOST}"

                withCredentials([
                    sshUserPrivateKey(
                        credentialsId: "${env.SSH_CREDENTIALS_ID}",
                        keyFileVariable: 'SSH_KEY',
                        usernameVariable: 'SSH_USER'
                    ),
                    usernamePassword(
                        credentialsId: 'nexus-credentials',
                        usernameVariable: 'NEXUS_USER',
                        passwordVariable: 'NEXUS_PWD'
                    )
                ]) {
                    sh """
                        #!/bin/bash
                        set -e -x

                        ssh -i \$SSH_KEY -o StrictHostKeyChecking=no ${REMOTE_USER}@${REMOTE_HOST} << 'EOF'
                            set -e -x

                            # -------- 写入 Docker 认证信息(使用 shell 生成 base64) --------
                            echo "【0】配置 Docker 认证"
                            mkdir -p ~/.docker
                            AUTH=\$(echo -n "${NEXUS_USER}:${NEXUS_PWD}" | base64)
                            cat > ~/.docker/config.json <<EOL
{
  "auths": {
    "${REGISTRY}": {
      "auth": "\${AUTH}"
    }
  }
}
EOL

                            # -------- 拉取最新镜像 --------
                            echo "【1】拉取镜像 ${IMAGE_NAME}:${IMAGE_TAG}"
                            docker pull ${IMAGE_NAME}:${IMAGE_TAG}

                            # -------- 停止并删除旧容器(若有) --------
                            echo "【2】停止并删除旧容器 ${CONTAINER_NAME}"
                            docker stop ${CONTAINER_NAME} 2>/dev/null || true
                            docker rm ${CONTAINER_NAME} 2>/dev/null || true

                            # -------- 启动新容器(挂载配置目录) --------
                            echo "【3】启动新容器,映射端口 ${HOST_PORT}:${CONTAINER_PORT}"
                            docker run -d \\
                                --name ${CONTAINER_NAME} \\
                                --restart=always \\
                                -p ${HOST_PORT}:${CONTAINER_PORT} \\
                                -v ${CONFIG_HOST_PATH}:${CONFIG_CONTAINER_PATH} \\
                                ${IMAGE_NAME}:${IMAGE_TAG}

                            # -------- 等待并检查状态 --------
                            sleep 5
                            echo "【4】检查容器状态"
                            docker ps --filter "name=${CONTAINER_NAME}" --format "table {{.Names}}\t{{.Status}}\t{{.Image}}"

                            echo "========== 容器启动日志(尾部50行) =========="
                            docker logs --tail 50 ${CONTAINER_NAME}
                            echo "================================================"

                            echo "✅ 部署完成"
EOF
                    """
                }
                echo "远程部署流程执行完毕"
            }
        }
    }

    post {
        always {
            echo "【Post钩子】流水线构建结束"
        }
        success {
            cleanWs()
            echo "🎉 流水线全部执行成功!"
        }
        failure {
            echo "💥 流水线执行失败,请查看日志排查问题!"
        }
    }
}

部署结果

img

最近更新: 2026/7/31 20:12
Contributors: jysemel, kcnf
Prev
pipeline构建应用
Next
权限管理