学习Spring Boot:(二十三)Spring Boot 中使用 Docker
前言
简单的学习下怎么在 Spring Boot 中使用 Docker 进行构建,发布一个镜像,现在我们通过远程的 docker api 构建镜像,运行容器,发布镜像等操作。
这里只介绍两种方式:
- 远程命令 api (需要知道 Docker 命令)
- maven 插件 (不需要了解 Docker 命令)
开启 Docker api 远程访问
开启 docker api 远程操作的功能,
例如,centos 7 中在 /usr/lib/systemd/system/docker.service
,文件中,修改 ExecStart
的参数:
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
端口自定义设置即可。
重载所有修改过的配置文件,并且重启 docker,
systemctl daemon-reload
systemctl restart docker.service
需要注意的是,由于没有密码登陆任何权限验证,外网或者生产环境需要上证书使用。
命令方式构建镜像
这种方式其实非常简单,就是需要懂得 docker 命令,才能操作。
经过上面开启 Docker Api 后,我们可以使用网络环境操作 Docker 引擎了。
新建
Dockerfile
构建镜像文件,新创建一个文件夹,专门放构建镜像需要的文件,我创建的是/src/docker/
FROM java:8 EXPOSE 8080VOLUME /tmp ADD springboot-docker.jar app.jar ENTRYPOINT ["java","-jar","/app.jar"]
执行 maven 命令 ,将项目打包
mvn clean package --DskipTests
,然后将打好的 jar 包,也放入到Dockerfile
项目目录中。然后进入
src/docker
目录下执行 :docker -H tcp://xxx.xxx.xxx.xxx:2375 build -t test .
开始构建镜像:
Sending build context to Docker daemon 31.74MB Step 1/5 : FROM java:8---> d23bdf5b1b1b Step 2/5 : EXPOSE 8080---> Using cache---> 060a43a42146 Step 3/5 : VOLUME /tmp---> Using cache---> b4f88fde6181 Step 4/5 : ADD springboot-docker.jar app.jar---> 3a40188825b0 Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]---> Running in ab093916fc4c Removing intermediate container ab093916fc4c---> 45a3966feb60 Successfully built 45a3966feb60 Successfully tagged test:latest
?
使用 docker-maven-plugin构建镜像
在 maven 项目下加入 docker-maven-plugin
<!--打包docker插件相关参数的配置--><plugin><groupId>com.spotify</groupId><artifactId>docker-maven-plugin</artifactId><version>0.4.14</version><configuration><!--打包的镜像名--><imageName>${project.groupId}/${project.artifactId}</imageName><!--Dockerfile文件位置,以项目的 root 目录为根节点,建议到单独建立一个目录--><dockerDirectory>./src/docker/</dockerDirectory><!--Docker 远程的 API 地址及端口--><dockerHost>http://xxx.xxx.xxx.199:2375</dockerHost><imageTags><imageTag>latest</imageTag></imageTags><!--执行构建docker镜像的时候需要哪些文件,springboot项目指定 打包好的jar 镜像就好--><resources><resource><!--这里指定的文件是target中的jar文件--><targetPath>/</targetPath><directory>${project.build.directory}</directory><include>${project.build.finalName}.jar</include></resource></resources></configuration></plugin>
创建 Dockerfile
需要跟pom.xml
上面配置的路径保持一致,所以我的路径是 ${baseProjectFolder}/src/docker
的文件夹下新建一个文件 Dockerfile
,添加构建 docker 相关命令参数:
FROM java:8
EXPOSE 8080VOLUME /tmp
ADD springboot-docker.jar app.jar # 根据打包的jar 包文件名进行修改
ENTRYPOINT ["java","-jar","/app.jar"]
打包
在应用的根目录下执行命令(打包加 dokcer build):
$ mvn clean package docker:build -DskipTests
比如使用我的工程,进行打包后完成了 docker 的构建的信息:
[INFO] Building image com.wuwii/springboot-docker
Step 1/5 : FROM java:8---> d23bdf5b1b1b
Step 2/5 : EXPOSE 8080---> Running in b7936baae57f
Removing intermediate container b7936baae57f---> 060a43a42146
Step 3/5 : VOLUME /tmp---> Running in 65e2b8ac44d3
Removing intermediate container 65e2b8ac44d3---> b4f88fde6181
Step 4/5 : ADD springboot-docker.jar app.jar---> aa3762cda143
Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]---> Running in d9f5f63b9736
Removing intermediate container d9f5f63b9736---> 622a7d1e315c
ProgressMessage{id=null, status=null, stream=null, error=null, progress=null, progressDetail=null}
Successfully built 622a7d1e315c
Successfully tagged com.wuwii/springboot-docker:latest
使用镜像
进入安装 docker 的主机中,使用命令查看镜像(
IMAGE ID
和上面是一致的):$ docker image ls com.wuwii/springboot-docker REPOSITORY TAG IMAGE ID CREATED SIZE com.wuwii/springboot-docker latest 622a7d1e315c 22 minutes ago 659MB
运行容器:
$ docker run -d -p 8080:8080 --name learn com.wuwii/springboot-docker180fe4a7ddfc10c0cf2c37649ae1628e804564bfe1594ef05840e707801e6da3
监听 8080 端口,测试是否成功。
服务编排 compose
一般的我们的 WEB 项目会使用到很多外部工具,例如 Redis ,MYSQL, ES等,如果一个一个启动搭建部署,太麻烦了,还要测试如果把这个一套环境拿到别的地方还能用吗?
使用服务编排可以避免这些坑。
加入我们的项目中增加了 Mysql 的数据库,在根目录新建一个 docker-compose.yml
:
version: '3'
services:web:depends_on:- dbports:- "8080:8080" # 建议加上引号,如果单独两位数的数字,可能出现解析问题restart: always# build:# context: ./src/docker # Dockerfile 文件的目录,可以远程地址,绝对 or 相对# dockerfile: Dockerfile # 如果你的 Dockerfile 重命名了,需要指定image: test:latestenvironment:DB_HOST: db:3306DATABASE: learnDB_USERNAME: root # 测试用下 rootDB_PASSWORD: 123456 # # 建议使用 secretdb:image: mysql:5.7volumes:- db_data:/var/lib/mysqlrestart: alwaysenvironment:MYSQL_ROOT_PASSWORD: 123456MYSQL_DATABASE: learnMYSQL_USER: kronchanMYSQL_PASSWORD: 123456volumes:db_data: # 使用的数据卷必须声明
上面我使用的是前面已经构建好的镜像,然后执行的编排,更好的是直接使用 build
让它自己编排服务。
系统配置文件application.yml
使用缺省值的方式,不影响开发的使用:
spring:datasource:url: jdbc:mysql://${DB_HOST:localhost:3306}/${DATABASE:learn}?useSSL=false&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8username: ${DB_USERNAME:root}password: ${DB_PASSWORD:123456}driver-class-name: com.mysql.jdbc.Driverjpa:show-sql: truedatabase: mysqlhibernate:ddl-auto: updateproperties:hibernate:dialect: org.hibernate.dialect.MySQL57Dialect # 方言根据 数据库版本选择吧
也可以使用不同的 spring.profiles
指定不同的环境,在 docker-compose.yml
中覆盖执行命令指定环境也是常见做法的:command: mvn clean spring-boot:run -Dspring-boot.run.profiles=xxx
最后启动,在 docker-compose.yml
目录下执行 : docker-compose up
关闭服务 docker-compose down
注意
docker-compose 顺序的问题,这个是开始学习编排的时候需要注意的问题,如果上面的服务编排中 mysql 启动的慢, web 项目就会启动失败,它启动的时候不知道被依赖的服务是否启动完成,就会出现这样的问题。
解决的办法有以下几种:
- 足够的容错和重试机制,比如连接数据库,在初次连接不上的时候,服务消费者可以不断重试,直到连接上位置
- docker-compose拆分,分成两部分部署,将要先启动的服务放在一个docker-compose中,后启动的服务放在两一个docker-compose中,启动两次,两者使用同一个网络。
- 同步等待,使用
wait-for-it.sh
或者其他shell
脚本将当前服务启动阻塞,直到被依赖的服务加载完毕
wait-for-it
的github地址为:wait-for-it
总结
- 主要是写 Dockerfile 的时候最好单独的拿出一个文件夹来放它,我开始的时候就是直接放在项目的根路径,结果构建镜像的时候总是出现了将其他的文件也一起复制到了 Docker 目录中,WINDOW下使用 maven 插件操作这个需要注意这个上下文环境,不然很容易将一个磁盘的文件都拷贝进来了,初学者血的教训。解决办法就是单独创建一个文件夹,将需要的东西单独放置,就不用考虑这么多问题。
学习Spring Boot:(二十三)Spring Boot 中使用 Docker相关推荐
- 结束处理程序——Windows核心编程学习手札之二十三
结束处理程序 --Windows核心编程学习手札之二十三 使用SEH可以只关注程序要完成任务,而运行中发生的错误,系统将会发现并通知.Windows引入SHE是为了便于操作系统的开发,使用SHE所造成 ...
- OpenCV学习笔记(二十一)——绘图函数core OpenCV学习笔记(二十二)——粒子滤波跟踪方法 OpenCV学习笔记(二十三)——OpenCV的GUI之凤凰涅槃Qt OpenCV学习笔记(二十
OpenCV学习笔记(二十一)--绘图函数core 在图像中,我们经常想要在图像中做一些标识记号,这就需要绘图函数.OpenCV虽然没有太优秀的GUI,但在绘图方面还是做得很完整的.这里就介绍一下相关 ...
- Spring(二)--------Spring配置、DI依赖注入、Bean自动装配
Spring(二)--------Spring配置.DI依赖注入.Bean自动装配 5.Spring配置 5.1 别名 设置别名:第一种方式alias <!--其中name为ID的对应值--&g ...
- 强化学习系列文章(二十三):AirSim Python API图像与图像处理
强化学习系列文章(二十三):AirSim Python API图像与图像处理 参考网址:https://microsoft.github.io/AirSim/image_apis/#segmentat ...
- C语言学习(十二)C语言中的字符(宽字符与窄字符)、从字符谈谈C语言的编码、转义字符
C语言学习(十二)C语言中的字符(宽字符与窄字符).从字符谈谈C语言的编码.转义字符 目录 C语言学习(十二)C语言中的字符(宽字符与窄字符).从字符谈谈C语言的编码.转义字符 英文字符 字符的表示 ...
- Slicer学习笔记(二十三)slicer调试自带模块
Slicer学习笔记(二十三)slicer调试自带模块 1.调试Segment Editor模块下的Grow from seeds 2.调试文件与细节 2.1.masterImageData的调试信息 ...
- Spring 学习笔记(二)Spring AOP
前言 容器和AOP是Spring的两大核心.本文将来学习Spring AOP. AOP是什么? AOP在计算机科学领域还是相对年轻的概念,由Xerox PARC公司发明.Gregor Kiczales ...
- 和php交互的过程_JavaScript学习笔记(二十三) 服务器PHP
PHP PHP 一门后端语言 为什么要学习一个后端语言呢? 目前市场上的需求,要求前端人员掌握一个后端语言 方便和后端开发人员进行交互 基本组织架构 在讲后端语言之前,我们简单的了解一下我们基本的组织 ...
- Linux学习笔记(二十三) -- QT的安装和卸载
1.QT简介 Qt 是一个跨平台C++图形用户界面应用程序开发框架.它可以用来开发GUI程序和非GUI程序(比如控制台工具和服务器). 2.QT安装 使用如下命令: sudo apt-get inst ...
- Spring学习笔记(二十三)——实现网站微信扫码登录获取微信用户信息Demo
目录 微信扫码登录介绍 开发步骤 微信扫码登录示例 微信开放文档 遇到的问题 使用第三方工具实现网站微信扫码登录 开发前介绍 开发步骤 微信扫码登录获取微信用户信息Demo实现流程 实现效果 实现过程 ...
最新文章
- Serverless 解惑——函数计算如何安装字体
- nyoj-999 师傅又被妖怪抓走了
- 几个方便编程的C++特性
- 回归分析中的正则化问题
- 汇编软件的安装与实验一
- 二叉树祖先节点_二叉树的祖先
- NodeJS使用淘宝 NPM 镜像/NPM使用国内源
- python数据结构与算法第10讲_Python数据结构与算法10:基本结构:练习题1
- 掌握这些的Linux命令,你基本稳了
- 博弈论:寻找先手必胜策略——Grundy值
- jQuery增加删除修改tab导航特效
- 关于echarts中饼图设置颜色的方法
- 推荐广告相关名词ctr,cvr等
- 关于Qt中QMAKESPEC环境变量
- QT中事件及事件处理
- “禁止燃放烟花爆竹”社会治理创新活动
- 卸载完mathtype后,word加载项中还是有mathtype的解决方法
- ARM程序的镜像文件以及在内存中的分区
- 多商户商城系统功能拆解24讲-平台端分销会员
- 【Java基础】· IO流习题详解
热门文章
- [转载] Java中Scanner用法总结
- stl中map函数_map :: max_size()函数,以及C ++ STL中的Example
- scala 转换为字符串_如何在Scala中将字符串转换为布尔值?
- uselocale_Java扫描仪useLocale()方法与示例
- ruby 将字符串转为数组_Ruby程序将数组打印为字符串
- 块元素、行内块和内联元素_如何删除内联块元素之间的空间?
- python函数示例_带Python示例的float()函数
- C# WinForm窗体四周阴影效果
- Js实现动态插入删除文本框
- 第一次创建springboot框架项目