简体   繁体   English

如何使用jenkins将spring boot jar文件部署到EC2?

[英]How to deploy spring boot jar file to EC2 using jenkins?

i am trying to deploy the spring boot app to AWS EC2 instances. 我正在尝试将Spring Boot应用程序部署到AWS EC2实例。 i have seen lot of blog and tutorial explained deployment process completely which is understandable. 我已经看到很多博客和教程完全解释了部署过程,这是可以理解的。 i am struggling how to do continuous deployment or delivery in jenkins which main feature where spring boot app name or jar file name changes that time. 我正在努力如何在jenkins中进行连续部署或交付,这是Spring Boot应用程序名称或jar文件名随时间变化的主要功能。

my pipeline 我的管道

  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'"
        }
    }
}

} }

Server start and stop and restart are handled in shell script. 服务器启动,停止和重新启动均在Shell脚本中处理。

my start.sh 我的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

This start my server perfectly and works fine.. 这将完美启动我的服务器,并且工作正常。

here my doubt is currently in start.sh i am using same jar file name so it works fine but in production with version change jar file name also change how to handle that situation. 在这里,我的疑问是当前在start.sh中,我使用的是相同的jar文件名,因此它可以正常工作,但在生产中使用版本更改jar文件名也会更改如何处理这种情况。 Help me to know about that process. 帮助我了解该过程。 Where i can get that complete idea and everything thanks in advance 我在哪里可以得到完整的想法,在此先感谢一切

I must say you should maintain you artifact's version as a standard process for non-prod and prod deployment. 我必须说,您应该将工件的版本维护为非产品和产品部署的标准过程。 Usually in non-prod environment you can plan for SNAPSHOT version and in production you should go for RELEASE version which can be generated using mvn release prepare release perform using maven-release-plugin . 通常,在非产品环境中,您可以计划SNAPSHOT版本,而在生产环境中,您应该使用RELEASE版本,该版本可以使用mvn release prepare release perform生成,可以使用maven-release-plugin发布 It will bump up your pom version for next subsequent releases. 它将提升您的pom版本,以用于后续的后续发行。 You can store your artifact to AWS S3 or Artifactory or Nexus (for high availability ) like the ubuntu machine that you are referring here. 您可以将工件存储到AWS S3或Artifactory或Nexus(以实现高可用性),例如此处引用的ubuntu计算机。

Now I would suggest you should add one more stage named like stage('Release') where you should use using maven-release-plugin to release the version and store it to a separate path like 现在,我建议您再添加一个名为stage('Release')的阶段,在该阶段应使用maven-release-plugin发行版本并将其存储在单独的路径中,例如

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

and as per you stage('Build') should copy to another path like 并且根据您的stage('Build')应该复制到另一个路径,例如

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

You can execute stage ' Release ' and ' Prod-Deliver ' based on conditional input parameter of your Jenkins pipeline. 您可以根据Jenkins管道的条件输入参数执行阶段“ 发布 ”和“ 生产交付 ”。 Here would be a possible solution for a smooth CICD in your case. 在您的情况下,这可能是获得平滑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}'"
        }
    }

}
}

You have to add the condtion in your script file as well like below 您必须在脚本文件中添加条件,如下所示

#!/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

I would say keep the name of the final artifact as a constant name using the build.finalName and have a provision to keep the build version somewhere inside the build. 我会说,使用build.finalName将最终工件的名称保留为常量名称,并提供了将版本保留在内部的版本。

As I see that you use spring boot, You can save version information part of the build by using build-info goal of spring-boot-maven-plugin as shown below. 正如我看到的那样,您使用spring boot,可以通过使用spring-boot-maven-plugin build-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>

and access the maven build information via the actuator endpoint http://localhost:8080/actuator/info . 并通过执行器端点http://localhost:8080/actuator/info访问maven构建信息。

Or, You can get the version information saved in classpath:META-INF/build-info.properties by looking into the jar file by using the following command. 或者,通过使用以下命令查看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

This way the build version is not changed even when there was an accidental renaming of the file. 这样,即使意外重命名文件,构建版本也不会更改。

You could pass the filename as an argument to the shell script, ie modify the shell script like so: 您可以将文件名作为参数传递给shell脚本,即像这样修改shell脚本:

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

and then you would need to determine the correct filename to use, based on the build version, and pass that as an argument to the script in the Deliver stage. 然后您需要根据构建版本确定要使用的正确文件名,并将其作为参数传递给Deliver阶段中的脚本。

You can just rename the file when you do an scp 您可以在执行scp时重命名文件

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

In your case something like this 在你的情况下

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'

The above code takes whatever build version has been created by jenkins and at the time of copying it and renames it to "aws-0.0.1-SNAPSHOT.jar", so you dont have to modify your start.sh 上面的代码采用jenkins创建的任何构建版本,并在复制时将其重命名为“ aws-0.0.1-SNAPSHOT.jar”,因此您无需修改​​start.sh

PS generally when you deploy your final build(JAR) ensure that only the jar name is added as the description to the filename and not "-0.0.1-SNAPSHOT" PS通常,在部署最终版本(JAR)时,请确保仅将jar名称作为描述添加到文件名中,而不是“ -0.0.1-SNAPSHOT”

Hope it helps :) 希望能帮助到你 :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM