您的位置:首页 > 运维架构 > Docker

用 Docker、Gradle 来构建、运行、发布一个 Spring Boot 应用

2017-05-31 00:00 381 查看
摘要:用Docker、Gradle来构建、运行、发布一个SpringBoot应用

如何用Docker、Gradle来构建、运行、发布来一个SpringBoot应用。

Docker简介

Docker是一个Linux容器管理工具包,具备“社交”方面,允许用户发布容器的image(镜像),并使用别人发布的image。Dockerimage是用于运行容器化进程的方案,在本文中,我们将构建一个简单的SpringBoot应用程序。

有关Docker的详细介绍,可以移步至《简述Docker》。

前置条件

JDK1.8+

Gradle2.3+

Docker最新版。有关Docker在的安装,可以参阅《Docker在CentOS下的安装、使用》。如果你的电脑不是Linux系统,最好装个虚拟机,在虚拟机里面装个Linux,因为Docker的依赖Linux。

用Gradle构建项目

创建目录结构

项目的目录结构因符合Gradle的约定。

在*nix系统下执行mkdir-psrc/main/java/docker_spring_boot,生产如下结构:

1
2
3
4
5
6
└──src
└──main
└──java
└──com
└──waylau
└──docker_spring_boot

创建Gradle构建文件

build.gradle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
buildscript{
repositories{
mavenCentral()
}
dependencies{
classpath('org.springframework.boot:spring-boot-gradle-plugin:1.3.3.RELEASE')
//tag::build[]
classpath('se.transmode.gradle:gradle-docker:1.2')
//end::build[]
}
}

applyplugin:'java'
applyplugin:'eclipse'
applyplugin:'idea'
applyplugin:'spring-boot'
//tag::plugin[]
applyplugin:'docker'
//end::plugin[]

//Thisisusedasthedockerimageprefix(org)
group='gregturn'

jar{
baseName='docker-spring-boot-gradle'
version='1.0.0'
}

//tag::task[]
taskbuildDocker(type:Docker,dependsOn:build){
push=true
applicationName=jar.baseName
dockerfile=file('src/main/docker/Dockerfile')
doFirst{
copy{
fromjar
intostageDir
}
}
}
//end::task[]

repositories{
mavenCentral()
}

sourceCompatibility=1.8
targetCompatibility=1.8

dependencies{
compile("org.springframework.boot:spring-boot-starter-web")
testCompile("org.springframework.boot:spring-boot-starter-test")
}

taskwrapper(type:Wrapper){
gradleVersion='2.3'
}
SpringBootgradleplugin提供了很多方便的功能:

它收集的类路径上所有jar文件,并构建成一个单一的、可运行的“über-jar”(德语,相关解释可以移步至http://stackoverflow.com/questions/11947037/what-is-an-uber-jar),这使得它更方便地执行和传输服务。

编写SpringBoot应用

编写一个简单的SpringBoot应用:

src/main/java/com/waylau/docker_spring_boot/Application.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
packagecom.waylau.docker_spring_boot;

importorg.springframework.boot.SpringApplication;
importorg.springframework.boot.autoconfigure.SpringBootApplication;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RestController;

/**
*主应用入口
*@author<ahref="http://waylau.com">waylau.com</a>
*@date2016年3月19日
*/
@SpringBootApplication
@RestController
publicclassApplication{

@RequestMapping("/")
publicStringhome(){
return"HelloDockerWorld."
+"Welcometo<ahref='http://waylau.com'>waylau.com</a></li>";
}

publicstaticvoidmain(String[]args){
SpringApplication.run(Application.class,args);
}

}
解释下上面的代码:

类用@SpringBootApplication@RestController标识,可用SpringMVC来处理Web请求。

@RequestMapping将/映射到home(),并将”HelloDockerWorld”文本作为响应。

main()方法使用SpringBoot的SpringApplication.run()方法来启动应用。

运行程序

使用Gradle

编译:

1
gradlebuild
运行:

1
java-jarbuild/libs/docker-spring-boot-gradle-1.0.0.jar

访问项目

如果程序正确运行,浏览器访问http://localhost:8080/,可以看到页面“HelloDockerWorld.”字样。

将项目容器化

Docker使用Dockerfile文件格式来指定image层,

创建文件src/main/docker/Dockerfile:

1
2
3
4
FROMfrolvlad/alpine-oraclejdk8:slim
VOLUME/tmp
ADDdocker-spring-boot-gradle-1.0.0.jarapp.jar
ENTRYPOINT["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
解释下这个配置文件:

VOLUME指定了临时文件目录为/tmp。其效果是在主机/var/lib/docker目录下创建了一个临时文件,并链接到容器的/tmp。改步骤是可选的,如果涉及到文件系统的应用就很有必要了。/tmp目录用来持久化到Docker数据文件夹,因为SpringBoot使用的内嵌Tomcat容器默认使用/tmp作为工作目录

项目的jar文件作为“app.jar”添加到容器的

ENTRYPOINT执行项目app.jar。为了缩短Tomcat启动时间,添加一个系统属性指向“/dev/urandom”作为EntropySource

构建DockerImage

执行构建成为dockerimage:

1
gradlebuildbuildDocker

运行

运行DockerImage

1
dockerrun-p8080:8080-twaylau/docker-spring-boot-gradle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[root@waylauspring-boot]#dockerrun-p8080:8080-twaylau/docker-spring-boot-gradle

._________
/\\/___'_____(_)______\\\\
(()\___|'_|'_||'_\/_`|\\\\
\\/___)||_)|||||||(_||))))
'|____|.__|_||_|_||_\__,|////
=========|_|==============|___/=/_/_/_/
::SpringBoot::(v1.3.3.RELEASE)

2016-03-2008:45:51.276INFO1---[main]c.waylau.docker_spring_boot.Application:StartingApplicationv1.0.0on048fb623038fwithPID1(/app.jarstartedbyrootin/)
2016-03-2008:45:51.289INFO1---[main]c.waylau.docker_spring_boot.Application:Noactiveprofileset,fallingbacktodefaultprofiles:default
2016-03-2008:45:51.722INFO1---[main]ationConfigEmbeddedWebApplicationContext:Refreshingorg.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@669af5fc:startupdate[SunMar2008:45:51GMT2016];rootofcontexthierarchy
2016-03-2008:45:54.874INFO1---[main]o.s.b.f.s.DefaultListableBeanFactory:Overridingbeandefinitionforbean'beanNameViewResolver'withadifferentdefinition:replacing[Rootbean:class[null];scope=;abstract=false;lazyInit=false;autowireMode=3;dependencyCheck=0;autowireCandidate=true;primary=false;factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration;factoryMethodName=beanNameViewResolver;initMethodName=null;destroyMethodName=(inferred);definedinclasspathresource[org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]]with[Rootbean:class[null];scope=;abstract=false;lazyInit=false;autowireMode=3;dependencyCheck=0;autowireCandidate=true;primary=false;factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter;factoryMethodName=beanNameViewResolver;initMethodName=null;destroyMethodName=(inferred);definedinclasspathresource[org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2016-03-2008:45:57.893INFO1---[main]s.b.c.e.t.TomcatEmbeddedServletContainer:Tomcatinitializedwithport(s):8080(http)
2016-03-2008:45:57.982INFO1---[main]o.apache.catalina.core.StandardService:StartingserviceTomcat
2016-03-2008:45:57.984INFO1---[main]org.apache.catalina.core.StandardEngine:StartingServletEngine:ApacheTomcat/8.0.32
2016-03-2008:45:58.473INFO1---[ost-startStop-1]o.a.c.c.C.[Tomcat].[localhost].[/]:InitializingSpringembeddedWebApplicationContext
2016-03-2008:45:58.473INFO1---[ost-startStop-1]o.s.web.context.ContextLoader:RootWebApplicationContext:initializationcompletedin6877ms
2016-03-2008:45:59.672INFO1---[ost-startStop-1]o.s.b.c.e.ServletRegistrationBean:Mappingservlet:'dispatcherServlet'to[/]
2016-03-2008:45:59.695INFO1---[ost-startStop-1]o.s.b.c.embedded.FilterRegistrationBean:Mappingfilter:'characterEncodingFilter'to:[/*]
2016-03-2008:45:59.701INFO1---[ost-startStop-1]o.s.b.c.embedded.FilterRegistrationBean:Mappingfilter:'hiddenHttpMethodFilter'to:[/*]
2016-03-2008:45:59.703INFO1---[ost-startStop-1]o.s.b.c.embedded.FilterRegistrationBean:Mappingfilter:'httpPutFormContentFilter'to:[/*]
2016-03-2008:45:59.703INFO1---[ost-startStop-1]o.s.b.c.embedded.FilterRegistrationBean:Mappingfilter:'requestContextFilter'to:[/*]
2016-03-2008:46:00.862INFO1---[main]s.w.s.m.m.a.RequestMappingHandlerAdapter:Lookingfor@ControllerAdvice:org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@669af5fc:startupdate[SunMar2008:45:51GMT2016];rootofcontexthierarchy
2016-03-2008:46:01.166INFO1---[main]s.w.s.m.m.a.RequestMappingHandlerMapping:Mapped"{[/]}"ontopublicjava.lang.Stringcom.waylau.docker_spring_boot.Application.home()
2016-03-2008:46:01.189INFO1---[main]s.w.s.m.m.a.RequestMappingHandlerMapping:Mapped"{[/error],produces=[text/html]}"ontopublicorg.springframework.web.servlet.ModelAndVieworg.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2016-03-2008:46:01.190INFO1---[main]s.w.s.m.m.a.RequestMappingHandlerMapping:Mapped"{[/error]}"ontopublicorg.springframework.http.ResponseEntity<java.util.Map<java.lang.String,java.lang.Object>>org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2016-03-2008:46:01.302INFO1---[main]o.s.w.s.handler.SimpleUrlHandlerMapping:MappedURLpath[/webjars/**]ontohandleroftype[classorg.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-03-2008:46:01.302INFO1---[main]o.s.w.s.handler.SimpleUrlHandlerMapping:MappedURLpath[/**]ontohandleroftype[classorg.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-03-2008:46:01.438INFO1---[main]o.s.w.s.handler.SimpleUrlHandlerMapping:MappedURLpath[/**/favicon.ico]ontohandleroftype[classorg.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-03-2008:46:01.833INFO1---[main]o.s.j.e.a.AnnotationMBeanExporter:RegisteringbeansforJMXexposureonstartup
2016-03-2008:46:02.332INFO1---[main]s.b.c.e.t.TomcatEmbeddedServletContainer:Tomcatstartedonport(s):8080(http)
2016-03-2008:46:02.343INFO1---[main]c.waylau.docker_spring_boot.Application:StartedApplicationin13.194seconds(JVMrunningfor15.828)

访问项目

如果程序正确运行,浏览器访问http://localhost:8080/,可以看到页面“HelloDockerWorld.”字样。

推送image到DockerHub

首先,你在DockerHub要有注册账号,且创建了相应的库;

其次,docker推送前,先要登录,否则报unauthorized:accesstotherequestedresourceisnotauthorized的错误

执行:

1
dockerlogin
输出为:

1
2
3
4
5
6
[root@waylauspring-boot]#dockerlogin
Username:waylau
Password:
Email:waylau521@gmail.com
WARNING:logincredentialssavedin/root/.docker/config.json
LoginSucceeded
执行推送

1
dockerpushwaylau/docker-spring-boot-gradle
1
2
3
4
5
6
7
8
[root@waylauspring-boot]#dockerpushwaylau/docker-spring-boot-gradle
Thepushreferstoarepository[docker.io/waylau/docker-spring-boot-gradle]
751d29eef02e:Layeralreadyexists
4da3741f39c7:Pushed
5f70bf18a086:Layeralreadyexists
7e4d0cb13643:Layeralreadyexists
8f045733649f:Layeralreadyexists
latest:digest:sha256:eb4d5308ba1bb27489d808279e74784bda6761b3574f4298d746abba59b35164size:9415

镜像加速器

DockerHub在国外,有时候拉取Image极其缓慢,可以使用国内的镜像来实现加速

阿里云

1
2
echo"DOCKER_OPTS=\"--registry-mirror=https://yourlocation.mirror.aliyuncs.com\""|sudotee-a/etc/default/docker
sudoservicedockerrestart
其中https://yourlocation.mirror.aliyuncs.com是您在阿里云注册后的专属加速器地址:

DaoCloud

1
2
sudoecho“DOCKER_OPTS=\”\$DOCKER_OPTS–registry-mirror=http://your-id.m.daocloud.io-d\””>>/etc/default/docker
sudoservicedockerrestart
其中http://your-id.m.daocloud.io是您在DaoCloud注册后的专属加速器地址:

源码

获取项目源码,https://github.com/waylau/docker-demos中的samples/spring-boot-gradle

获取项目镜像,执行

1
dockerpullwaylau/docker-spring-boot-gradle

参考引用

http://spring.io/guides/gs/spring-boot-docker/
https://hub.docker.com/r/waylau/docker-spring-boot-gradle/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: