Spring Boot项目Docker化快速上手
开篇
服务部署是应用上线前的必需环节。大道至简,如何做到项目简单化、自动化甚至傻瓜式部署是考验DevOps的一大难题。从docker面世到k8s的脱颖而出,有越来越多的开源工具也在帮助开发和运维人员解决这些问题。
对于开发人员,了解和学习Docker可谓是迫在眉睫。网上有很多优秀的学习资源,当然了,本文的主角不全是docker,但也不无关系。
现在是CI时代。用过Jenkins,但对于个人或小型项目来说太笨重了,不过还有例如像Travis这样的轻量级CI可供我们选择。本文要介绍的不涉及CI工具,只需要借助Maven插件,就可以轻松打包SpringBoot项目到远程服务器,启动镜像即可部署上线。如果这描述适合你最近在捣腾的一些项目,可以继续往下看!
环境说明
- Docker v18.06.1-ce
- Spring Boot v2.0.4.RELEASE
配置准备
通过Maven将本地打包好的SpringBoot Jar包推送到远程Docker服务中,关键步骤就在于为Docker服务配置这个暴露端口。这步操作也简单,直接命令编辑vim /lib/systemd/system/docker.service
( 左侧为Ubuntu的路径; CentOS 的路径参考:/usr/lib/systemd/system/docker.service
),找到ExecStart=/usr/bin/dockerd -H fd://
这行,修改为ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:22375 -H unix:///var/run/docker.sock
(表示让Docker服务监听22375这个TCP端口),重启让配置生效:systemctl daemon-reload && systemctl restart docker
下面测试一下: curl localhost:22375/info
,如果有一堆信息出来就可以继续往下走:
curl localhost:22375/info
插件添加
没有Spring Boot项目可以自行新建,然后在pom.xml
中添加如下配置:
<build>
<!-- 最终Maven本地打包出来的jar包名称 -->
<finalName>example</finalName>
<defaultGoal>package</defaultGoal>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<!-- GitHub: https://github.com/spotify/docker-maven-plugin -->
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.1.1</version>
<configuration>
<!-- 远程镜像名称 -->
<imageName>example</imageName>
<forceTags>true</forceTags>
<imageTags>
<imageTag>${project.version}</imageTag>
<imageTag>latest</imageTag>
</imageTags>
<dockerHost>http://服务器IP:22375</dockerHost>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
参考上述配置,还需要新建docker
文件夹,然后创建Dockerfile
文件,并添加如下内容:
# 指定基础镜像(必需且为第一条指令,scratch是空白镜像)
FROM openjdk:8-jre-alpine
# MAINTAINER已经过期,具体参考:https://docs.docker.com/engine/reference/builder/#label
LABEL author-name="author-email"
# 为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,
# 这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。
VOLUME /opt/tmp
# 在 COPY 和 ADD 指令中选择的时候,可以遵循这样的原则,
# 所有文件复制使用 COPY 指令,仅在需要自动解压缩的场合使用 ADD 指令
COPY example.jar example.jar
# JVM参数可选
CMD ["java","-jar","-Xms64m","-Xmx64m","example.jar"]
# EXPOSE 指令仅仅是声明的是运行时容器提供服务的端口
# 用于帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;
EXPOSE 8080
构建运行
用maven命令构建远程镜像:mvn clean package docker:build -Dmaven.test.skip=true
在远程服务器上运行服务:docker run --name example -d -p 8080:8080 example
可以查看服务启动情况:docker logs -f example
学习资源
参考链接
SpringBoot | 第十四章:基于Docker的简单部署 docker-socket设置 Docker开发部署Node小结
- 利用HSTS嗅探浏览器历史纪录的三个漏洞
- Verilog代码设计风格
- Yaffs_checkptrw
- 那些 Shell、Awk 中自动隐式类型转换的“坑”
- 浏览器 HTTP 协议缓存机制详解
- 详解 Windows 下 Eclipse CDT 配置 C/C++ 编译环境
- 硬核乘法器的Verilog HDL 调用
- Web 自动化测试与智能爬虫利器:PhantomJS 简介与实战
- 浅谈 Scala 中下划线的用途
- Java 多线程之 Runnable VS Thread 及其资源共享问题
- 块RAM的Verilog HDL调用
- 玩转千位分隔符输出
- DCM 模块的Verilog HDL 调用
- Python RPC 远程调用脚本之 RPyC 实践
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 利用C#编写的绕过360安全卫士添加系统用户
- 小生归一(七)sprintf字符串格式化漏洞
- FastAdmin后台GetShell
- scRNA-seq Clustering
- Dizzy Blog
- LeetCode 392. 判断子序列
- LeetCode 5473. 灯泡开关 IV
- LeetCode 5472. 重新排列字符串
- BootStrap 导航栏实现下滑消失,上滑出现
- 七日Python之路--第六天
- 超性感的React Hooks(六)自定义hooks的思维方式
- 七日Python之路--第五天(之找点乐子)
- 超性感的React Hooks(七)useReducer
- 七日Python之路--第四天(之Django官方文档)
- 六、setTimeout与循环闭包经典面试题详解