Jenkins+Docker+Springboot单机版持续集成部署

    技术2024-10-30  22

    Jenkins+Docker+SpringBoot持续集成流程说明

    安装配置jenkins 安装jenkins可直接官网下载对应的jar包直接运行,也可使用docker运行,下载完后直接运行,并下载docker,jdk,maven等,并在jenkins->系统设置->全局工具配置里配置好对应的安装目录等。

    配置全局凭据及应用服务器SSH 如果是使用私有代码仓库以及镜像仓库,则可以在全局配置里添加对应的用户名及密码,以便在jenkins配置脚本里引用。 jenkins->凭据->系统->全局凭据->添加凭据里添加对应仓库的登录账号以及密码,id(配置脚本引用时使用),描述等。

    jenkins->系统管理->系统配置->Publish over SSH 模块里添加要执行部署脚本的应用服务器的登录用户密码等。

    新建jenkins pipeline任务 在流水线模块,可点击流水线语法去生成对应的脚本(如git拉取代码,编译打包,push镜像,执行远程ssh脚本等)

    项目引入dockerfile-maven-plugin插件 使用该插件将项目打包成docker镜像 <plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>${dockerfile.plugin.version}</version> <configuration> <repository>${project.artifactId}</repository> <buildArgs> <!-- 提供参数向Dockerfile传递 --> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> </plugin> 项目目录下编写Dockerfile FROM sapmachine/jdk11 VOLUME /tmp # dockerfile-maven-plugin配置,即插件配置的<JAR_FILE>标签值 ARG JAR_FILE # 将jar包添加到容器中并更名为app.jar ADD ${JAR_FILE} app.jar RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime RUN echo Asia/Shanghai >/etc/timezone # 运行jar包 RUN bash -c "touch /app.jar" EXPOSE 8080 # 以profile = prod 启动项目 ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=prod","-jar","/app.jar"]
    jenkins pipeline脚本及部署脚本(可修改修改直接使用)
    Jenkinsfile node { //构建版本的名称 def tag = "latest" // 仓库私服地址 def docker_registry = "xxxxxxx" // 命名空间 def docker_namespace = "mayfly" // 项目名 def project_name = "test-xxx" stage('拉取代码') { // credentialsId:全局凭证的id url:git地址 git branch: 'master', credentialsId: 'git_test', url: 'https:git_project.git' } // 定义镜像名称 def imageName = "${project_name}:${tag}" def tagName = "${docker_registry}/${docker_namespace}/${imageName}" stage('编译,构建镜像') { // 编译并安装公共工程 sh "mvn clean -Dmaven.test.skip=true install" // 编译,并使用dockerfile-maven-plugin插件命令构建本地镜像 sh "mvn -f ${project_name} clean package -Dmaven.test.skip=true dockerfile:build" } stage("发布镜像至仓库") { // 给镜像打标签 sh "docker tag ${imageName} ${tagName}" withCredentials([usernamePassword(credentialsId: 'docker_repo', passwordVariable: 'password', usernameVariable: 'username')]) { // 登录 sh "docker login -u ${username} -p ${password} ${docker_registry}" // 上传镜像 sh "docker push ${tagName}" } // 删除本地镜像 sh "docker rmi -f ${imageName}" sh "docker rmi -f ${tagName}" } stage("服务器执行部署脚本") { // execCommand: 执行部署脚本命令及传递参数 sshPublisher(publishers: [sshPublisherDesc(configName: 'eatlife-server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/usr/local/java/deploy.sh $docker_registry $docker_namespace $project_name $tag", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '\'\'')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) } } deploy.sh #! /bin/sh #接收外部参数,由jenkinsfile执行部署脚本时传递 docker_registry=$1 docker_namespace=$2 project_name=$3 tag=$4 imageName=$docker_registry/$docker_namespace/$project_name:$tag echo "镜像名: $imageName" echo "项目名: $project_name" #查询容器是否存在,存在则删除 containerId=$(docker ps -a | grep -w "${project_name}":"${tag}" | awk '{print $1}') if [ "$containerId" != "" ] ; then #停掉容器 docker stop "$containerId" #删除容器 docker rm "$containerId" echo "成功删除容器" fi #查询镜像是否存在,存在则删除 imageId=$(docker images | grep -w "$project_name" | awk '{print $3}') if [ "$imageId" != "" ] ; then #删除镜像 docker rmi -f "$imageId" echo "成功删除镜像" fi # 登录docker私服 docker login -u user -p pwd "$docker_registry" # 下载镜像 docker pull "$imageName" # 启动容器,指定网络并暴露80端口 docker run -itd --name "$project_name" --network mayfly-net -p80:8080 "$imageName" echo "容器启动成功"
    Processed: 0.009, SQL: 9