How to deploy spring boot jar file to EC2 using jenkins?
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. It will bump up your pom version for next subsequent releases. You can store your artifact to AWS S3 or Artifactory or Nexus (for high availability ) like the ubuntu machine that you are referring here.
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
ubuntu@00.00.00.00:/home/ubuntu/RELEASE/${version}
and as per you stage('Build') should copy to another path like
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.Here would be a possible solution for a smooth CICD in your case.
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/bashrelease_type=$1version=$2if [[ ${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 &fiecho $! > /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.
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.
<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
.
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.
$> unzip -qc your-artifact-name.jar META-INF/build-info.properties#Properties#Fri May 04 17:43:06 IST 2018build.time=2018-05-04T12\:13\:06.225Zbuild.artifact=your-artifact-namebuild.group=com.examplebuild.name=your-artifact-namebuild.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, i.e. modify the shell script like so:
#!/bin/bashnohup 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.