用 Docker 構(gòu)建、運(yùn)行、發(fā)布一個 Spring Boot 應(yīng)用
2016-03-20??Docker?Spring Boot??Docker?Spring Boot?鏡像?Docker Hub
本文演示了如何用 Docker 構(gòu)建、運(yùn)行、發(fā)布來一個 Spring Boot 應(yīng)用。
Docker 簡介
Docker?是一個 Linux 容器管理工具包,具備“社交”方面,允許用戶發(fā)布容器的 image (鏡像),并使用別人發(fā)布的 image。Docker image 是用于運(yùn)行容器化進(jìn)程的方案,在本文中,我們將構(gòu)建一個簡單的 Spring Boot 應(yīng)用程序。
有關(guān) Docker 的詳細(xì)介紹,可以移步至?《簡述 Docker》
前置條件
JDK 1.8+
Maven 3.0+
Docker 最新版。有關(guān) Docker 在的安裝,可以參閱?《Docker 在 CentOS 下的安裝、使用》。 如果你的電腦不是 Linux 系統(tǒng),最好裝個虛擬機(jī),在虛擬機(jī)里面裝個 Linux ,因?yàn)?Docker 的依賴 Linux。
用 Maven 構(gòu)建項(xiàng)目
創(chuàng)建目錄結(jié)構(gòu)
項(xiàng)目的目錄結(jié)構(gòu)因符合 Maven 的約定。
在 *nix 系統(tǒng)下執(zhí)行?mkdir -p src/main/java/docker_spring_boot?,生產(chǎn)如下結(jié)構(gòu) :
└── src
└── main
└── java
└── com
└── waylau
└── docker_spring_boot
創(chuàng)建 pom.xml 文件
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4.0.0
com.waylau
docker-spring-boot
jar
1.0.0
docker-spring-boot
Getting started with Spring Boot and Docker
org.springframework.boot
spring-boot-starter-parent
1.3.3.RELEASE
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
com.spotify
docker-maven-plugin
0.4.3
${docker.image.prefix}/${project.artifactId}
src/main/docker
/
${project.build.directory}
${project.build.finalName}.jar
UTF-8
waylau
1.3.3.RELEASE
Spring Boot Maven plugin?提供了很多方便的功能:
它收集的類路徑上所有 jar 文件,并構(gòu)建成一個單一的、可運(yùn)行的“über-jar”,這使得它更方便地執(zhí)行和傳輸服務(wù)。
它搜索的?public static void main()?方法來標(biāo)記為可運(yùn)行的類。
它提供了一個內(nèi)置的依賴解析器,用于設(shè)置版本號以匹配?Spring Boot 的依賴。您可以覆蓋任何你想要的版本,但它會默認(rèn)選擇的 Boot 的版本集。
Spotify 的?docker-maven-plugin?插件是用于構(gòu)建 Maven 的 Docker Image
imageName指定了鏡像的名字,本例為?waylau/docker-spring-boot
dockerDirectory指定 Dockerfile 的位置
resources是指那些需要和 Dockerfile 放在一起,在構(gòu)建鏡像時使用的文件,一般應(yīng)用 jar 包需要納入。本例,只需一個 jar 文件。
編寫 Spring Boot 應(yīng)用
編寫一個簡單的 Spring Boot 應(yīng)用 :
src/main/java/com/waylau/docker_spring_boot/Application.java:
package com.waylau.docker_spring_boot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 主應(yīng)用入口
* @author waylau.com
* @date 2016年3月19日
*/
@SpringBootApplication
@RestController
public class Application {
@RequestMapping("/")
public String home() {
return "Hello Docker World."
+ "
Welcome to waylau.com";
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
解釋下上面的代碼:
類用?@SpringBootApplication?@RestController?標(biāo)識,可用 Spring MVC 來處理 Web 請求。
@RequestMapping?將?/?映射到?home()?,并將"Hello Docker World" 文本作為響應(yīng)。
main()?方法使用 Spring Boot 的?SpringApplication.run()?方法來啟動應(yīng)用。
運(yùn)行程序
使用 Maven
編譯:
mvn package
運(yùn)行:
java -jar target/docker-spring-boot-1.0.0.jar
訪問項(xiàng)目
如果程序正確運(yùn)行,瀏覽器訪問?http://localhost:8080/,可以看到頁面 “Hello Docker World.” 字樣。
將項(xiàng)目容器化
Docker 使用?Dockerfile?文件格式來指定 image 層,
創(chuàng)建文件?src/main/docker/Dockerfile:
FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD docker-spring-boot-1.0.0.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
解釋下這個配置文件:
VOLUME?指定了臨時文件目錄為/tmp。其效果是在主機(jī)?/var/lib/docker?目錄下創(chuàng)建了一個臨時文件,并鏈接到容器的/tmp。改步驟是可選的,如果涉及到文件系統(tǒng)的應(yīng)用就很有必要了。/tmp目錄用來持久化到 Docker 數(shù)據(jù)文件夾,因?yàn)?Spring Boot 使用的內(nèi)嵌 Tomcat 容器默認(rèn)使用/tmp作為工作目錄
項(xiàng)目的 jar 文件作為 "app.jar" 添加到容器的
ENTRYPOINT?執(zhí)行項(xiàng)目 app.jar。為了縮短?Tomcat 啟動時間,添加一個系統(tǒng)屬性指向 "/dev/urandom" 作為 Entropy Source
構(gòu)建 Docker Image
執(zhí)行構(gòu)建成為 docker image:
mvn package docker:build
運(yùn)行
運(yùn)行 Docker Image
docker run -p 8080:8080 -t waylau/docker-spring-boot
[root@waylau spring-boot]# docker run -p 8080:8080 -t waylau/docker-spring-boot
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.3.3.RELEASE)
2016-03-20 08:45:51.276 INFO 1 --- [ main] c.waylau.docker_spring_boot.Application : Starting Application v1.0.0 on 048fb623038f with PID 1 (/app.jar started by root in /)
2016-03-20 08:45:51.289 INFO 1 --- [ main] c.waylau.docker_spring_boot.Application : No active profile set, falling back to default profiles: default
2016-03-20 08:45:51.722 INFO 1 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@669af5fc: startup date [Sun Mar 20 08:45:51 GMT 2016]; root of context hierarchy
2016-03-20 08:45:54.874 INFO 1 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'beanNameViewResolver' with a different definition: replacing [Root bean: 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); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: 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); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2016-03-20 08:45:57.893 INFO 1 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-03-20 08:45:57.982 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2016-03-20 08:45:57.984 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.0.32
2016-03-20 08:45:58.473 INFO 1 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2016-03-20 08:45:58.473 INFO 1 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 6877 ms
2016-03-20 08:45:59.672 INFO 1 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2016-03-20 08:45:59.695 INFO 1 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2016-03-20 08:45:59.701 INFO 1 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2016-03-20 08:45:59.703 INFO 1 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2016-03-20 08:45:59.703 INFO 1 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2016-03-20 08:46:00.862 INFO 1 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@669af5fc: startup date [Sun Mar 20 08:45:51 GMT 2016]; root of context hierarchy
2016-03-20 08:46:01.166 INFO 1 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public java.lang.String com.waylau.docker_spring_boot.Application.home()
2016-03-20 08:46:01.189 INFO 1 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2016-03-20 08:46:01.190 INFO 1 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2016-03-20 08:46:01.302 INFO 1 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-03-20 08:46:01.302 INFO 1 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-03-20 08:46:01.438 INFO 1 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-03-20 08:46:01.833 INFO 1 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2016-03-20 08:46:02.332 INFO 1 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2016-03-20 08:46:02.343 INFO 1 --- [ main] c.waylau.docker_spring_boot.Application : Started Application in 13.194 seconds (JVM running for 15.828)
訪問項(xiàng)目
如果程序正確運(yùn)行,瀏覽器訪問?http://localhost:8080/,可以看到頁面 “Hello Docker World.” 字樣。
推送 image 到 Docker Hub
首先,你在 Docker Hub 要有注冊賬號,且創(chuàng)建了相應(yīng)的庫;
其次,docker 推送前,先要登錄,否則報unauthorized: access to the requested resource is not authorized的錯誤
執(zhí)行:
docker login
輸出為:
[root@waylau spring-boot]# docker login
Username: waylau
Password:
Email: waylau521@gmail.com
WARNING: login credentials saved in /root/.docker/config.json
Login Succeeded
執(zhí)行推送
docker push waylau/docker-spring-boot
[root@waylau spring-boot]# docker push waylau/docker-spring-boot
The push refers to a repository [docker.io/waylau/docker-spring-boot]
751d29eef02e: Layer already exists
4da3741f39c7: Pushed
5f70bf18a086: Layer already exists
7e4d0cb13643: Layer already exists
8f045733649f: Layer already exists
latest: digest: sha256:eb4d5308ba1bb27489d808279e74784bda6761b3574f4298d746abba59b35164 size: 9415
鏡像加速器
Docker Hub 在國外,有時候拉取 Image 極其緩慢,可以使用國內(nèi)的鏡像來實(shí)現(xiàn)加速
阿里云
echo "DOCKER_OPTS=\"--registry-mirror=https://yourlocation.mirror.aliyuncs.com\"" | sudo tee -a /etc/default/docker
sudo service docker restart
其中?https://yourlocation.mirror.aliyuncs.com?是您在阿里云注冊后的專屬加速器地址:
DaoCloud
sudo echo “DOCKER_OPTS=\”\$DOCKER_OPTS –registry-mirror=http://your-id.m.daocloud.io -d\”” >> /etc/default/docker
sudo service docker restart
其中?http://your-id.m.daocloud.io?是您在 DaoCloud 注冊后的專屬加速器地址:
源碼
獲取項(xiàng)目源碼,?https://github.com/waylau/docker-demos?中的?samples/spring-boot
獲取項(xiàng)目鏡像, 執(zhí)行
docker pull waylau/docker-spring-boot
參考引用
http://spring.io/guides/gs/spring-boot-docker/
https://yq.aliyun.com/articles/2930?utm_source=tuicool&utm_medium=referral
https://hub.docker.com/r/waylau/docker-spring-boot/
??在 Tomcat 中配置 SSL/TLS 以支持 HTTPS??Docker 在 openSUSE 下的安裝、使用??
==============================================================
docker-maven-plugin打包鏡像,并上傳到私有倉庫
docker-maven-plugin打包鏡像,并上傳到私有倉庫_docker-maven-plugin 推送私有倉庫_zhangjunli的博客-CSDN博客文章來源:http://www.zghlxwxcb.cn/news/detail-503146.html
docker-maven-plugin 插件就是為了幫助我們在Maven工程中,通過簡單的配置,自動生成鏡像并推送到倉庫中。文章來源地址http://www.zghlxwxcb.cn/news/detail-503146.html
到了這里,關(guān)于用 Docker 構(gòu)建、運(yùn)行、發(fā)布一個 Spring Boot 應(yīng)用的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!