Jenkins集成部署SpringBoot
Jenkins集成部署SpringBoot
1. 前言
隨著業務的增長,需求也開始增多,每個需求的大小,開發周期,發布時間都不一致。基于微服務的系統架構,功能的疊加,對應的服務的數量也在增加,大小功能的快速迭代,更加要求部署的快速化,智能化。因此,傳統的人工部署已經心有余而力不足。
持續集成,持續部署,持續交互對于微服務開發來說,是提高團隊整體效率不可或缺的一環。合理的使用CI,CD能夠極大的提高了生產效率,也提高了產品的交互質量。
本文主要介紹的內容有如下幾點
- docker安裝Jenkins
- Jenkins安裝后的初始化和相關配置
- SpringBoot的docker打包鏡像
- Jenkins從Github拉取源碼
- Jenkins將SpringBoot項目部署成docker
閱讀本文需要對docker和linux有一定的了解
2. Jenkins安裝及配置
2.1 安裝Jenkins
Jenkins的安裝采用的是docker版本安裝,相對與其他版本的安裝,會簡單很多
運行Jenkins容器命令如下
docker run \
--privileged=true \
--name jenkins \
-d \
-u root \
-p 8080:8080 \
-v /usr/bin/docker:/usr/bin/docker \
-v /usr/local/soft/jenkins:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-e TZ=Asia/Shanghai \
-v "$HOME":/home \
jenkins/jenkins
相關參數說明
- --privileged:使得容器內的用戶擁有root權限
- --name:運行容器的名稱
- -d: 容器后臺運行
- -u:指定容器的用戶
- -v /usr/bin/docker:/usr/bin/docker:將宿主的/var/run/docker.sock文件掛載到容器內的同樣位置,從而讓容器內可以通過unix socket調用宿主的Docker引擎
- -v /usr/bin/docker:/usr/bin/docker:同上
- -v /usr/local/soft/jenkins:/var/jenkins_home:將Jenkins的數據目錄掛載到主機目錄/usr/local/soft/jenkins
- -e:指定時區
2.2 初始化Jenkins
- 瀏覽器打開Jenkins地址
(http://127.0.0.1/):8080

找到Jenkins映射目錄,找到相應文件,查看密碼,登錄
- 安裝插件,一般直接選擇推薦的插件安裝

- 安裝插件較慢,等待片刻即可

- 創建系統管理員

- 安裝完成,進入下一步

2.3 配置相應的Jenkins
2.3.1 maven
- 安裝maven
因為使用Jenkins默認的maven下載包比較慢,所以這里我自行安裝maven
進入設置->全局工具設置

這里我安裝的是maven3.6.1
- 修改maven的配置
修改Jenkins安裝目錄下的maven配置,我的maven在主機的目錄為/usr/local/soft/jenkins/tools/hudson.tasks.Maven_MavenInstallation/maven_3.6.1,自己可自行判斷目錄
配置文件修改后為
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!--
| This is the configuration file for Maven. It can be specified at two levels:
|
| 1. User Level. This settings.xml file provides configuration for a single user,
| and is normally provided in ${user.home}/.m2/settings.xml.
|
| NOTE: This location can be overridden with the CLI option:
|
| -s /path/to/user/settings.xml
|
| 2. Global Level. This settings.xml file provides configuration for all Maven
| users on a machine (assuming they're all using the same Maven
| installation). It's normally provided in
| ${maven.conf}/settings.xml.
|
| NOTE: This location can be overridden with the CLI option:
|
| -gs /path/to/global/settings.xml
|
| The sections in this sample file are intended to give you a running start at
| getting the most out of your Maven installation. Where appropriate, the default
| values (values used when the setting is not specified) are provided.
|
|-->
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
<localRepository>/var/jenkins_home/tools/hudson.tasks.Maven_MavenInstallation/MavenRepository</localRepository>
<!-- interactiveMode
| This will determine whether maven prompts you when it needs input. If set to false,
| maven will use a sensible default value, perhaps based on some other setting, for
| the parameter in question.
|
| Default: true
<interactiveMode>true</interactiveMode>
-->
<!-- offline
| Determines whether maven should attempt to connect to the network when executing a build.
| This will have an effect on artifact downloads, artifact deployment, and others.
|
| Default: false
<offline>false</offline>
-->
<!-- pluginGroups
| This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e.
| when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers
| "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list.
|-->
<pluginGroups>
<pluginGroup>com.spotify</pluginGroup>
<!-- pluginGroup
| Specifies a further group identifier to use for plugin lookup.
<pluginGroup>com.your.plugins</pluginGroup>
-->
</pluginGroups>
<!-- proxies
| This is a list of proxies which can be used on this machine to connect to the network.
| Unless otherwise specified (by system property or command-line switch), the first proxy
| specification in this list marked as active will be used.
|-->
<proxies>
<!-- proxy
| Specification for one proxy, to be used in connecting to the network.
|
<proxy>
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<username>proxyuser</username>
<password>proxypass</password>
<host>proxy.host.net</host>
<port>80</port>
<nonProxyHosts>local.net|some.host.com</nonProxyHosts>
</proxy>
-->
</proxies>
<!-- servers
| This is a list of authentication profiles, keyed by the server-id used within the system.
| Authentication profiles can be used whenever maven must make a connection to a remote server.
|-->
<servers>
<!-- server
| Specifies the authentication information to use when connecting to a particular server, identified by
| a unique name within the system (referred to by the 'id' attribute below).
|
| NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are
| used together.
|
<server>
<id>deploymentRepo</id>
<username>repouser</username>
<password>repopwd</password>
</server>
-->
<!-- Another sample, using keys to authenticate.
<server>
<id>siteServer</id>
<privateKey>/path/to/private/key</privateKey>
<passphrase>optional; leave empty if not used.</passphrase>
</server>
-->
</servers>
<!-- mirrors
| This is a list of mirrors to be used in downloading artifacts from remote repositories.
|
| It works like this: a POM may declare a repository to use in resolving certain artifacts.
| However, this repository may have problems with heavy traffic at times, so people have mirrored
| it to several places.
|
| That repository definition will have a unique id, so we can create a mirror reference for that
| repository, to be used as an alternate download site. The mirror site will be the preferred
| server for that repository.
|-->
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<mirrorOf>central</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
</mirrors>
<!-- profiles
| This is a list of profiles which can be activated in a variety of ways, and which can modify
| the build process. Profiles provided in the settings.xml are intended to provide local machine-
| specific paths and repository locations which allow the build to work in the local environment.
|
| For example, if you have an integration testing plugin - like cactus - that needs to know where
| your Tomcat instance is installed, you can provide a variable here such that the variable is
| dereferenced during the build process to configure the cactus plugin.
|
| As noted above, profiles can be activated in a variety of ways. One way - the activeProfiles
| section of this document (settings.xml) - will be discussed later. Another way essentially
| relies on the detection of a system property, either matching a particular value for the property,
| or merely testing its existence. Profiles can also be activated by JDK version prefix, where a
| value of '1.4' might activate a profile when the build is executed on a JDK version of '1.4.2_07'.
| Finally, the list of active profiles can be specified directly from the command line.
|
| NOTE: For profiles defined in the settings.xml, you are restricted to specifying only artifact
| repositories, plugin repositories, and free-form properties to be used as configuration
| variables for plugins in the POM.
|
|-->
<profiles>
<!-- profile
| Specifies a set of introductions to the build process, to be activated using one or more of the
| mechanisms described above. For inheritance purposes, and to activate profiles via <activatedProfiles/>
| or the command line, profiles have to have an ID that is unique.
|
| An encouraged best practice for profile identification is to use a consistent naming convention
| for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 'user-brett', etc.
| This will make it more intuitive to understand what the set of introduced profiles is attempting
| to accomplish, particularly when you only have a list of profile id's for debug.
|
| This profile example uses the JDK version to trigger activation, and provides a JDK-specific repo.
<profile>
<id>jdk-1.4</id>
<activation>
<jdk>1.4</jdk>
</activation>
<repositories>
<repository>
<id>jdk14</id>
<name>Repository for JDK 1.4 builds</name>
<url>http://www.myhost.com/maven/jdk14</url>
<layout>default</layout>
<snapshotPolicy>always</snapshotPolicy>
</repository>
</repositories>
</profile>
-->
<!--
| Here is another profile, activated by the system property 'target-env' with a value of 'dev',
| which provides a specific path to the Tomcat instance. To use this, your plugin configuration
| might hypothetically look like:
|
| ...
| <plugin>
| <groupId>org.myco.myplugins</groupId>
| <artifactId>myplugin</artifactId>
|
| <configuration>
| <tomcatLocation>${tomcatPath}</tomcatLocation>
| </configuration>
| </plugin>
| ...
|
| NOTE: If you just wanted to inject this configuration whenever someone set 'target-env' to
| anything, you could just leave off the <value/> inside the activation-property.
|
<profile>
<id>env-dev</id>
<activation>
<property>
<name>target-env</name>
<value>dev</value>
</property>
</activation>
<properties>
<tomcatPath>/path/to/tomcat/instance</tomcatPath>
</properties>
</profile>
-->
</profiles>
<!-- activeProfiles
| List of profiles that are active for all builds.
|
<activeProfiles>
<activeProfile>alwaysActiveProfile</activeProfile>
<activeProfile>anotherAlwaysActiveProfile</activeProfile>
</activeProfiles>
-->
</settings>
修改的位置分別為:
- maven本地倉庫的位置:
<localRepository>/var/jenkins_home/tools/hudson.tasks.Maven_MavenInstallation/MavenRepository</localRepository>
- mvn打包docker的插件,不添加會報錯
<pluginGroup>com.spotify</pluginGroup>
- 阿里云鏡像加速
<mirror> <id>alimaven</id> <name>aliyun maven</name> <mirrorOf>central</mirrorOf> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> </mirror>
2.3.2 配置環境變量
系統管理->系統設置
添加環境變量

添加的環境變量為:
MAVEN_HOME
/var/jenkins_home/tools/hudson.tasks.Maven_MavenInstallation/maven_3.6.1
Path
$Path:$MAVEN_HOME/bin:
2. SpringBoot項目配置
3.1 Dockerfile文件編寫
FROM java:latest
ENV SERVER_PORT 8080
ENV CONSUL_SERVER 127.0.0.1
ENV JVM_MEMORY 512M
COPY ./target/*.jar /tmp
RUN cp -f ./tmp/*.jar /app.jar
EXPOSE 8080
CMD echo "The application is starting..." && \
java -Xmx${JVM_MEMORY} -jar /app.jar
3.2 pom文件編寫
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.tao</groupId>
<artifactId>jenkins</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jenkins</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<docker.image.prefix>SpringBoot-jenkins</docker.image.prefix>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>aliyun-repos</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.11</version>
<configuration>
<imageName>mytest/${project.artifactId}</imageName>
<dockerDirectory>./</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.3 項目github地址
https://github.com/boolean-dev/jenkins.git
3. Jenkins部署
3.1 源碼管理
填寫Github的項目地址即可

3.2 項目構建參數
- maven打包
選擇maven的版本,并且執行maven構建命令
clean install -Dmaven.test.skip=true
-
執行shell
mvn docker:build echo "which docker" docker -v echo "當前docker 鏡像:" echo "啟動容器----->" docker images docker run --name springboot -p 8080:8080 -d mytest/jenkins echo "啟動服務成功!"

注:第一次執行shell的時候,因為springboot容器還未運行,所以無需停止和移除。所以第二次構建容器的時候,運行前需提前停止和移除容器,所以采用以下的shell
mvn docker:build echo "which docker" docker -v echo "當前docker 鏡像:" echo "啟動容器----->" docker stop springboot echo "移除舊容器" docker rm springboot docker images docker run --name springboot -p 8080:8080 -d mytest/jenkins echo "啟動服務成功!"
3.3 構建項目
可能在構建的過程中還會存在部分bug,只需查看相應日志,再google,一般都能解決。
構建完成后,在宿主機上執行docker ps查看容器是否運行

如圖,部署成功了

4. 后記
本篇博客實現了簡單的SpringBoot、jenkins和docker繼承部署,基本上全是運行在docker容器中,由此可見docker確實十分強大。
但是本篇博客之講了簡單的集成部署,并且采用的是自由式風格的編排,現主流的編排是使用流水線,那樣更加便捷,并且功能更加強大。
現階段還存在的缺點:
- 使用自由式風格以及shell的編排模塊,部署大量項目時繁雜
- 本次部署是Jenkins部署項目是在宿主機上,具有很大的局限性
- 歷史鏡像尚未保存
- 不能夠多分枝部署
- 未實現github提交代碼,自動更新
- 鏡像存儲在本地,未存儲在阿里云等鏡像倉庫中
后期可能進行的優化:
- 鏡像存儲在阿里云鏡像倉庫中,并且根據git的tag對鏡像進行備份
- 多分枝集成部署
- 實現github鉤子程序
- docker運行采用swarm集群或者K8s集群,便于管理集群
- ...
5. 參考鏈接
解放雙手 | Jenkins + gitlab + maven 自動打包部署項目
使用 Jenkins 自動部署 Docker 服務(一、Jenkins 搭建篇)

浙公網安備 33010602011771號