实现思路
- 安装Docker
- 安装Docker Jenkins,我更喜欢用Docker来部署环境
- 运行Jenkins环境,安装插件:Git、Maven、Config File Provider、SSH。Git用来拉取代码,Maven负责打包,SSH用来上传打包文件到应用服务器
- 添加任务,配置信息,让Jenkins生成Jar包
- 在应用服务器上编写脚本,将收到的Jar包生成Docker镜像并重新运行。所以应用服务器也是部署的Docker
实现步骤
Docker安装略过
Docker Jenkins
version: "3"
services:
jenkins:
image: jenkins/jenkins:lts-centos7-jdk8
network_mode: mynetwork
container_name: jenkins
ports:
- 8080:8080
- 50000:50000
volumes:
- /etc/localtime:/etc/localtime
- /home/mycontainers/jenkins/jenkins_home:/var/jenkins_home
- /home/mycontainers/jenkins/data:/data
执行:
docker-compose -f jenkins.yml up
如果报错:
jenkins | touch: cannot touch ‘/var/jenkins_home/copy_reference_file.log’: Permission denied
jenkins | Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?
那么就给这个jenkins_home文件夹赋予权限:
chmod 777 jenkins_home
容器启动成功会输出以下内容:
jenkins | Jenkins initial setup is required. An admin user has been created and a password generated.
jenkins | Please use the following password to proceed to installation:
jenkins |
jenkins | 4e26fb69f5ea42eab61dad85d199c16e
jenkins |
jenkins | This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
记住这个密钥:4e26fb69f5ea42eab61dad85d199c16e,登录Jenkins的要用到。
密钥会保存在指定路径下,在这里也可以查看到:
/var/jenkins_home/secrets/initialAdminPassword
访问:http://mylocalhost:8080 进入登录页。
输入密钥后需要等待Jenkins加载一段时间,然后就会出现插件选择页面:
我们不需要安装推荐的插件,只要选择性的安装几个必要的就可以。
点击无,取消所有已勾选的插件,后面再添加:
然后创建管理员用户:
后面一直点确定就可以,这样我们就进来了Jenkins首页,现在页面是英文的,可以根据需要安装中文插件。
Jenkins汉化(可选)
在这里我们可以安装需要的插件:
点击Install without restart进行安装,安装完成是这样的:
注意:汉化需要重启容器才可以生效。
docker restart jenkins
换源(可选)
如果觉得插件的安装太慢,可以修改配置文件换源:
修改hudson.model.UpdateCenter.xml:
<?xml version='1.1' encoding='UTF-8'?>
<sites>
<site>
<id>default</id>
<url>https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json</url>
</site>
</sites>
同样需要重启容器。
Git、Maven、Config File Provider、SSH插件
和汉化插件同理,搜索插件并安装即可:
注意看插件名字哦。
创建SpringBoot项目
来一个最简单的SpringBoot应用:
项目名:mavenDemo
pom.xml
<?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>
<groupId>com.cc</groupId>
<artifactId>mavenDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/>
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--springboot启动器-->
<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>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<!--指定可以用来打包的配置文件1-->
<profile>
<!--开发环境-->
<id>dev</id>
<properties>
<activatedProperties>dev</activatedProperties>
</properties>
<activation>
<!--默认情况下使用dev开发配置-->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<!--生产环境-->
<id>prod</id>
<properties>
<activatedProperties>prod</activatedProperties>
</properties>
</profile>
</profiles>
<build>
<!--指定打包的配置文件2-->
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<finalName>app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
XML中我们配置了动态环境 (activatedProperties),这样可以很方便的切换打包环境。
配置文件
application.yml:
server:
port: 8888
spring:
profiles:
active: @activatedProperties@
application-dev.yml:
env: dev
application-prod.yml:
env: prod
Application.java
package com.cc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Test Controller
package com.cc.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@Value("${env}")
private String env;
@GetMapping("/")
public String env() {
return env;
}
}
上传SpringBoot项目到Git上
比如Gitee,新建一个项目,把代码上传到这里,然后我们得到一个Git地址:
配置Maven
现在需要配置Maven,一般和我们平时开发时用的一致,或者和生产环境一致,我这里用的是Maven3.6.3:
滚到下面找到这个:
配置Maven settings.xml
通常我们都要配置这个,Jenkins中的Maven m2的没有settings.xml的,所以需要上面安装的插件:Config File Provider,安装后就会在Jenkins管理中多出来一个选项:
添加一个Maven settings.xml
下一步就到配置内容了:
提交即可,现在我们就有了一个叫MySetttings.xml的Maven配置文件。
回到刚刚的全局工具配置,设置Maven配置为我们刚创建的settings:
这里有两个,一个默认settings,一个默认全局settings,都搞一样的就可以,这样后面Maven项目会自动选用这个配置文件。
连接宿主机/目标服务器
在用Jenkins打包完成后,我们需要将Jar包上传到目标服务器,所以还需要配置,同上Maven配置的地方,找到Configure System,一直滚下去找到SSH Servers:
准备工作
新建任务
准备工作做好了,现在可以新建任务了:
然后我们需要逐一进行配置:
源码管理
源码在Gitee上,我们把Gitee项目的链接拷贝过来,因为Git项目是私有的,所以会提示报错,我们还需要给一个授权,最简单的就是在Credentials里面配置Gitee的账号密码:
添加完之后就可以选择了:
触发器
可以用Gitee的Hook触发,也可以轮询,这里不配置,就用默认的,需要触发的时候手动点击就好,简单快速入门。
Build
因为创建的任务是Maven类型,所以可以设置Root POM,默认pom.xml即可,然后是Goals and options,用maven打包命令:
构建后操作
结合之前添加的SSH主机,实现在构建后上传Jar包到SSH主机的操作。
宿主机(目标服务器)编写启动应用脚本
生成Jar包后,我们需要制作成镜像并运行容器,所以现在编写脚本放到宿主机里。
宿主机的构建思路是这样的:
-
假设工作目录为:/home/projects
-
Jenkins上传的Jar包放到:/home/project/maveDemo
-
/home/projects准备脚本:
- Dockerfile:制作镜像脚本,生成一个Java容器
- run.sh:光有Java容器还不行,加多个运行脚本,内容是java -jar xxx
- deploy.sh:部署脚本,整合上面两个的操作,也是Jenkins任务完成后要执行的脚本
Dockerfile:
FROM openjdk:8 RUN mkdir -p /home WORKDIR /home COPY . . ENTRYPOINT ["bash", "run.sh"]run.sh:
java -jar app.jardeploy.sh:
#!/bin/bash # 应用名,应该和应用目录名一致,且注意docker镜像不能用大写 projectName=$1 echo "进入拷贝Dockerfile和run.sh到应用目录中..." cp Dockerfile $1 cp run.sh $1 echo "进入应用目录,删除旧镜像和旧容器..." cd $1 docker stop $1 docker rm -f $1 imageName=$projectName:latest docker rmi $imageName echo "获取容器路径..." containerPath="/home/mycontainers" echo "制作新镜像并运行新容器..." echo $imageName docker build -t $imageName . docker run --name $projectName -itd -p 8888:8888 --restart=always -v /etc/localtime:/etc/localtime -v $containerPath/$projectName/data:/data $imageName echo "部署完成。"
保存
最后保存即可,以上是最简单的配置方式,这里没有时间和篇幅来完全讲述。
运行任务
回到Dashboard,点击运行按钮:
在这里有工作列表,点进去可以查看运行日志:
第一次执行有很多依赖需要加载,所以会慢一些。
看输出:
[JENKINS] Archiving /var/jenkins_home/workspace/mavenDemo/pom.xml to com.cc/mavenDemo/1.0-SNAPSHOT/mavenDemo-1.0-SNAPSHOT.pom
[JENKINS] Archiving /var/jenkins_home/workspace/mavenDemo/target/app.jar to com.cc/mavenDemo/1.0-SNAPSHOT/mavenDemo-1.0-SNAPSHOT.jar
channel stopped
SSH: Connecting from host [89d37b7b64ad]
SSH: Connecting with configuration [local] ...
SSH: EXEC: completed after 11,451 ms
SSH: Disconnecting configuration [local] ...
SSH: Transferred 1 file(s)
Finished: SUCCESS
成功生成了Jar包,并且将Jar包上传到了目标服务器,EXEC: completed after 11,451 ms指在目标服务器上脚本的执行时间,现在可以到目标服务器上看看日志,或者查看应用是否成功部署。