问题
i am trying to deploy the spring boot app to AWS EC2 instances. 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.
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.
my 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. Help me to know about that process. Where i can get that complete idea and everything thanks in advance
回答1:
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/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:
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 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.
回答3:
You could pass the filename as an argument to the shell script, i.e. modify the shell script like so:
#!/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.
回答4:
You can just rename the file when you do an 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
P.S 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"
Hope it helps :)
来源:https://stackoverflow.com/questions/50186447/how-to-deploy-spring-boot-jar-file-to-ec2-using-jenkins