如何使用 jenkins 将 spring 引导 jar 文件部署到 EC2?
How to deploy spring boot jar file to EC2 using jenkins?
我正在尝试将 spring 启动应用程序部署到 AWS EC2 实例。我看过很多博客和教程,完全解释了部署过程,这是可以理解的。我正在努力如何在 jenkins 中进行持续部署或交付,其中 spring 引导应用程序名称或 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 文件名也改变了如何处理这种情况。
帮助我了解那个过程。我在哪里可以得到完整的想法和一切
提前致谢
我会说使用 build.finalName
将最终工件的名称保留为常量名称,并提供将构建版本保留在构建内部某处的规定。
据我所知,您使用 spring 引导,您可以使用 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>
并通过执行器端点访问 Maven 构建信息 http://localhost:8080/actuator/info
。
或者,您可以通过使用以下命令查看 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
这样即使文件被意外重命名,构建版本也不会改变。
您可以将文件名作为参数传递给 shell 脚本,即像这样修改 shell 脚本:
#!/bin/bash
nohup java -jar /home/ubuntu/ > /home/ubuntu/log.txt 2>&1 &
echo $! > /home/ubuntu/pid.file
然后您需要根据构建版本确定要使用的正确文件名,并将其作为参数传递给交付阶段的脚本。
您可以在执行 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”
希望对您有所帮助:)
我必须说,您应该将工件的版本维护为非生产和生产部署的标准流程。通常在非产品环境中,您可以计划 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=
version=
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
我正在尝试将 spring 启动应用程序部署到 AWS EC2 实例。我看过很多博客和教程,完全解释了部署过程,这是可以理解的。我正在努力如何在 jenkins 中进行持续部署或交付,其中 spring 引导应用程序名称或 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 文件名也改变了如何处理这种情况。 帮助我了解那个过程。我在哪里可以得到完整的想法和一切 提前致谢
我会说使用 build.finalName
将最终工件的名称保留为常量名称,并提供将构建版本保留在构建内部某处的规定。
据我所知,您使用 spring 引导,您可以使用 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>
并通过执行器端点访问 Maven 构建信息 http://localhost:8080/actuator/info
。
或者,您可以通过使用以下命令查看 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
这样即使文件被意外重命名,构建版本也不会改变。
您可以将文件名作为参数传递给 shell 脚本,即像这样修改 shell 脚本:
#!/bin/bash
nohup java -jar /home/ubuntu/ > /home/ubuntu/log.txt 2>&1 &
echo $! > /home/ubuntu/pid.file
然后您需要根据构建版本确定要使用的正确文件名,并将其作为参数传递给交付阶段的脚本。
您可以在执行 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”
希望对您有所帮助:)
我必须说,您应该将工件的版本维护为非生产和生产部署的标准流程。通常在非产品环境中,您可以计划 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=
version=
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