【问题标题】:How to deploy spring boot jar file to EC2 using jenkins?如何使用 jenkins 将 Spring Boot jar 文件部署到 EC2?
【发布时间】:2018-10-15 14:54:48
【问题描述】:

我正在尝试将 Spring Boot 应用程序部署到 AWS EC2 实例。我看过很多博客和教程完全解释了部署过程,这是可以理解的。我正在努力如何在 jenkins 中进行持续部署或交付,哪个主要功能在那时 Spring Boot 应用程序名称或 jar 文件名会发生变化。

我的管道

  pipeline {
    agent any

    tools{
       maven 'localmaven' 
    }
    stages {
        stage('Build') { 
            steps {
               sh 'mvn clean package' 
            }
            post {
               success {
                    echo 'Now Archiving...'
                    archiveArtifacts artifacts: '**/target/*.jar'
                   }
              } 
          }


    stage('Deliver') {
        steps {
             sh 'scp -v -o StrictHostKeyChecking=no  -i /var/lib/jenkins/secrets/mykey target/*.jar ubuntu@00.00.00.00:/home/ubuntu'
             sh "sshpass -p password ssh -o StrictHostKeyChecking=no -i /var/lib/jenkins/secrets/mykey ubuntu@00.00.00.00 '/home/ubuntu/start.sh'"
        }
    }
}

}

服务器启动、停止和重启在 shell 脚本中处理。

我的 start.sh

#!/bin/bash
nohup java -jar /home/ubuntu/aws-0.0.1-SNAPSHOT.jar > /home/ubuntu/log.txt 2>&1 &
echo $! > /home/ubuntu/pid.file

这完美地启动了我的服务器并且工作正常..

这里我的疑问是目前在 start.sh 我使用相同的 jar 文件名,所以它工作正常,但在生产中使用版本更改 jar 文件名也会改变如何处理这种情况。 帮助我了解该过程。我在哪里可以获得完整的想法和一切 在此先感谢

【问题讨论】:

    标签: java bash spring-boot jenkins continuous-deployment


    【解决方案1】:

    我必须说,您应该将工件的版本作为非产品和产品部署的标准流程来维护。通常在非生产环境中,您可以计划 SNAPSHOT 版本,而在生产环境中,您应该选择 RELEASE 版本,该版本可以使用mvn release prepare release perform 使用maven-release-plugin 生成。它将提升您的 pom 版本以供下一个后续版本使用。您可以将您的工件存储到 AWS S3 或 Artifactory 或 Nexus(用于高可用性),例如您在此处引用的 ubuntu 机器。

    现在我建议您应该再添加一个名为 stage('Release') 的阶段,您应该使用 maven-release-plugin 来发布版本并将其存储到单独的路径中,例如

    ubuntu@00.00.00.00:/home/ubuntu/RELEASE/${version}

    并且根据你的阶段('Build')应该复制到另一个路径,比如

    ubuntu@00.00.00.00:/home/ubuntu/SNAPSHOT/${version}

    您可以根据 Jenkins 管道的条件输入参数执行阶段“Release”和“Prod-Deliver”。 在您的情况下,这将是一个平滑 CICD 的可能解决方案。

       pipeline {
        agent any
    
        tools{
           maven 'localmaven' 
        }
        stages {
            stage('Build') { 
                steps {
                   sh 'mvn clean install' 
                }
                post {
                   success {
                        echo 'Now Archiving...'
                       }
                  } 
              }
    
            stage('Release') { 
                steps {
                   sh 'elease:prepare release:perform' 
                }
                post {
                   success {
                        ////
                       }
                  } 
              }
    
          stage('NonProd-Deliver') {
              steps {
                   /*
                   You can extract the version from pom.xml,replace you project location in jenkins workspace in the below command
                   */
                   sh 'version=$(echo -e 'setns x=http://maven.apache.org/POM/4.0.0\ncat /x:project/x:version/text()' | xmllint --shell ${YOUR_PROJECT_LOCATION}/pom.xml | grep -v /)'
                   sh 'scp -v -o StrictHostKeyChecking=no  -i /var/lib/jenkins/secrets/mykey target/*.jar ubuntu@00.00.00.00:/home/ubuntu/SNAPSHOT/${version}'
                   sh "sshpass -p password ssh -o StrictHostKeyChecking=no -i /var/lib/jenkins/secrets/mykey ubuntu@00.00.00.00 '/home/ubuntu/start.sh nonprod $version'"
              }
          }
    
           stage('Prod-Deliver') {
            steps {
                  /*
                   For production release you should pass the version as a parameter to your jenkins pipeline which is going to be in production
                   */
                 sh 'scp -v -o StrictHostKeyChecking=no  -i /var/lib/jenkins/secrets/mykey target/*.jar ubuntu@00.00.00.00:/home/ubuntu/RELEASE/${version} '
                 sh "sshpass -p password ssh -o StrictHostKeyChecking=no -i /var/lib/jenkins/secrets/mykey ubuntu@00.00.00.00 '/home/ubuntu/start.sh prod ${version}'"
            }
        }
    
    }
    }
    

    您必须在脚本文件中添加条件,如下所示

    #!/bin/bash
    release_type=$1
    version=$2
    if [[ ${release_type} == "prod" ]]; then
      # non snapshot release to production env
      nohup java -jar /home/ubuntu/RELEASE/${version}/aws-0.0.1.jar > /home/ubuntu/log.txt 2>&1 & 
    else
      # snapshot release to non production env
      nohup java -jar /home/ubuntu/SNAPSHOT/${version}/aws-0.0.1-SNAPSHOT.jar > /home/ubuntu/log.txt 2>&1 &
    fi
    echo $! > /home/ubuntu/pid.file
    

    【讨论】:

      【解决方案2】:

      我会说使用build.finalName 将最终工件的名称保留为常量名称,并规定将构建版本保留在构建中的某个位置。

      我看到你使用spring boot,你可以使用spring-boot-maven-pluginbuild-info目标来保存构建的版本信息部分,如下所示。

        <build>
          <finalName>your-artifact-name</finalName>
          <plugins>
            <plugin>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-maven-plugin</artifactId>
              <executions>
                <execution>
                  <goals>
                    <goal>build-info</goal>
                  </goals>
                </execution>
              </executions>
            </plugin>
          </plugins>
        </build>
      

      并通过执行器端点 http://localhost:8080/actuator/info 访问 maven 构建信息。

      或者,您可以使用以下命令查看jar文件,获取保存在classpath:META-INF/build-info.properties中的版本信息。

      $> unzip -qc your-artifact-name.jar META-INF/build-info.properties
      #Properties
      #Fri May 04 17:43:06 IST 2018
      build.time=2018-05-04T12\:13\:06.225Z
      build.artifact=your-artifact-name
      build.group=com.example
      build.name=your-artifact-name
      build.version=1.0.0.SNAPSHOT
      

      这样,即使文件意外重命名,构建版本也不会更改。

      【讨论】:

        【解决方案3】:

        您可以将文件名作为参数传递给 shell 脚本,即像这样修改 shell 脚本:

        #!/bin/bash
        nohup java -jar /home/ubuntu/$1 > /home/ubuntu/log.txt 2>&1 &
        echo $! > /home/ubuntu/pid.file
        

        然后您需要根据构建版本确定要使用的正确文件名,并将其作为参数传递给交付阶段的脚本。

        【讨论】:

        • 如何将其作为 n 参数传递?
        • @Robin Green - $1 表示当前工作目录中的第一个可用文件名。
        • @Pranavadurai 不,它表示调用脚本时脚本的第一个参数。
        【解决方案4】:

        您可以在执行 scp 时重命名文件

        scp filename username@remote.host.net.:filenewname
        

        在你的情况下是这样的

        sh 'scp -v -o StrictHostKeyChecking=no  -i /var/lib/jenkins/secrets/mykey target/*.jar ubuntu@00.00.00.00:/home/ubuntu:aws-0.0.1-SNAPSHOT.jar'
        

        以上代码采用 jenkins 创建的任何构建版本,并在复制时将其重命名为“aws-0.0.1-SNAPSHOT.jar”,因此您不必修改 start.sh

        P.S 通常,当您部署最终构建 (JAR) 时,请确保仅将 jar 名称添加为文件名的描述,而不是“-0.0.1-SNAPSHOT”

        希望对你有帮助:)

        【讨论】:

        • 通过这种方法我们硬编码这个文件名总是正确的。有什么方法可以预测文件名没有硬代码或任何东西
        • @ion 我们正在硬编码文件的最终名称,该文件将被部署到服务器中(根据您的问题)......我不确定我完全理解你的意思想要 ....为什么要预测使用 maven 构建的文件的名称?上面的代码 (target/*.jar) 采用任何(filename) JAR 构建在目标文件夹中并重命名它...
        猜你喜欢
        • 2018-02-15
        • 2021-06-01
        • 1970-01-01
        • 2016-08-16
        • 2020-10-03
        • 1970-01-01
        • 2018-08-30
        • 2017-05-04
        • 2015-04-14
        相关资源
        最近更新 更多