流程 原理简述
很久之前就想部署一套jenkins+docker+github 自动化部署系统了。。无奈之前对docker的理解不够深入,对命令理解也不够透彻,所以一碰壁很多,知道最近这两天对docker有了更深入的理解,我又开始了尝试。
1 先说一下想实现的功能。
我的想法是,实现我本地编辑代码,提交到github以后,打开jenkins,点击构建,然后 jenkins就从github上拉代码,然后自动使用maven打包,使用Docker构建镜像并运行。
这样我们的工作就简化成了,编辑代码,提交到github,然后一键部署到服务器,爽歪歪。
前期准备:
一台linux服务器(我买的某云服务器,装的是ubuntu系统)
springboot的部署方式有两种 war包和jar包,我们本例使用的war包的部署方式,jar包部署大同小异,最后再说。
总结:
1 Docker的使用对linux内核版本有要求。
建议升到 4.0以上 。。 如果在打镜像的过程中出现异常,先去排查一下linux内核版本是否太低。
2 jenkins 安装以后
- 执行本地shell 需要给jenkins root权限 否则在执行shell脚本的时候可能会异常
- ssh远程shell 需要用户是具有root权限的,否置执行有的需要root权限指令可能会异常
3 一步一步来 先只测试GIT 然后 加上maven 然后加上 shell
注意多看控制台输出找错误原因
4 我的工程目录
5 Docker file 和tomcat配置
在你jenkins 编译生成WAR包,实际上就已经成功一半了,,,将war 包 dockerfile server.xml 三个文件移到一个单独的目录,比如/home/xixixi就挺好。。然后。就是最后一步,,使用shell命令进行打镜像发布的操作
如下是我的dockerfile
FROM tomcat
WORKDIR /usr/local/tomcat
WORKDIR /usr/local/tomcat/webapps1/
COPY server.xml /usr/local/tomcat/conf/
COPY target/webdemo.war /usr/local/tomcat/webapps1
run echo "Asia/Shanghai" > /etc/timezone
ENV LANG C.UTF-8
EXPOSE 2345
我使用的是2345 端口,所以tomcat 默认的8080 ,我在此基础上又添加了一个2345的端口,,同理你可以将多个微服务部署到一个tomcat上。
如下是我的tomcat的配置
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/>
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml"/>
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"/>
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="challenger_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b"/>
</Host>
</Engine>
</Service>
<Service name="hello">
<Connector port="2345" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"/>
<Connector port="8031" protocol="AJP/1.3" redirectPort="7031"/>
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps1"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="columbia_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b"/>
</Host>
</Engine>
</Service>
</Server>
6 打war包的时候springboot要注意的地方(jar包不用)
- 添加一个类 继承SpringBootServletInitializer,与启动类平级,或者直接使用启动类 重写configure方法
如下
@SpringBootApplication
public class WebappApplication extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(WebappApplication.class, args);
}
@Override
public SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(WebappApplication.class);
}
}
7 pom.xml 的相关
- maven不同环境打包添加 这样根据maven打包命令的 -p dev 或者 test 就可以用不同的打包设置
<packaging>${project.packaging}</packaging>
<profiles>
<profile>
<!-- 本地开发环境 -->
<id>dev</id>
<properties>
<profileActive>dev</profileActive>
<project.packaging>jar</project.packaging>
</properties>
<activation>
<!-- 设置默认激活这个配置 -->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<!-- 发布环境 -->
<id>test</id>
<properties>
<profileActive>test</profileActive>
<project.packaging>war</project.packaging>
</properties>
</profile>
<profile>
<!-- 测试环境 -->
<id>prod</id>
<properties>
<profileActive>prod</profileActive>
<project.packaging>jar</project.packaging>
</properties>
</profile>
</profiles>
- 设置打成的war包的名称
<build>
<finalName>**webdemo**</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
8 访问路径!!!
如果你镜像运行成功,什么都没问题,访问就是error404,记得在路径端口号后面第一个路径是你的finalName
如果你的controller是这个
@GetMapping("/hello/{data}")
public String hello(@PathVariable String data) {
return data;
}
那么你的路径是
http://xxx.xxx.xxx.xxx:port/你的build标签中的finalName/hello/data
9 docker 进入容器里面一探究竟
docker 镜像启动以后,可以进入容器里面,看看里面的详细内容
看看 war包是否被放在正确的webapps下面,war是否被自动解压。
10 jenkins配置
构建其实只用3个地方 git+build+post(Step)
jenkins 如果安装了插件需要重启jenkins。
- 我这里没有用到docker的镜像仓库,因为我的docke发布环境和jenkins装在一个服务器上,,jenkins使用maven build之后,直接使用shell命令用docker构建镜像发布
- 如果你的docker和jenkins不在一台服务器,那么你需要将上面生成的镜像打tag然后推到镜像仓库,然后通过ssh 远程操作正式服务的docker服务器执行shell拉取镜像并运行
打jar包更简单
dockerFile 如下
FROM java:8-alpine
ADD eurekaServer.jar app.jar
EXPOSE 1234
ENTRYPOINT ["java","-jar","/app.jar"]