Spring Boot 项目打包为 Docker 镜像

说明

先提一下整个流程。

Spring Boot 项目构建 jar 包,Docker 再把 jar 包打包为 Docker image。

流程是这样,再提一下细节。

  • jar 包可以在 java 环境直接执行 java -jar appname.jar 启动。而 Docker 的任务就相当于封装 jar 包,java 环境, 以及 java -jar appname.jar 这条指令。
  • Docker 打包 jar 包需要一个 Dockerfile 文件,这个文件相当于一个配置,告诉 Docker 应该如何打包,如何启动 jar 包。
  • 本地生成了 Docker image,想要把这个镜像部署到服务器,需要把 image 导出。这属于 Docker 命令了,这里不提。

既然知道流程了,怎么实现呢?

两种方式,第一种很直观,自己构建 jar 包,然后在本地手动打包镜像。

第二种,则是通过配置(这里使用 Gradle),实现整个打包的流程。

注意

流程大致可以分为两步,生成 jar 包,生成镜像。每一步都会遇到坑,慢慢来……

首先确保生成的 jar 包可以通过 java -jar appname.jar 执行。

可能会遇到 找不到主类等错误……

方式一

一 构建 jar 包

首先构建 jar 包,

可以 build artifacts。

建议在根目录下执行 gradle build 或者 gradlew build

先测试一下 jar 包能不能正常运行。

java -jar appname.jar

可能会出现找不到主类之类的问题。

二 创建镜像

然后把 jar 包与 Dockerfile 放在同一目录下

docker/blog.jar

docker/Dockerfile

执行

docker build -t [要生成的镜像名] .

注意哈,后面有个点「.」。

Dockerfile 是打包 docker image 所需的配置文件

比如

1
2
3
4
5
6
7
8
9
10
## Dockerfile
FROM aglover/java8-pier
VOLUME ["/tmp"]
ADD blog.jar app.jar
## blog.jar 是目录下的 jar 包
## app.jar 是 jar 包存放在 Docker 里的名字
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
## 这一条就是 Docker 里执行 jar 包,相应的 后面的 app.jar 就是 Docker 内 jar 包名
EXPOSE 8082
## 暴露端口 无所谓吧,Docker 启动容器可以自定义

这里很明显也能看出 Docker 内部还是用的 java -jar appname.jar 来运行。

三 运行

注意,运行需要指明 REPOSITORY TAG,

docker run -p 8082:8082 -t REPOSITORY:TAG

docker run -p 8082:8082 -t cn.hqweay/blog-backend:1.0

注意啊,不这样会启动失败……这问题搞了好久。

疑问

我在操作过程中去除了创建 Spring Boot 项目时自带的 Tomcat 依赖,不去不知道能不能行。

方式二

springboot + gradle + docker 配置

参考

https://juejin.im/post/5b27b7ac51882574c32c6588

说明

这里配置可以根据项目信息自动生成 Dockerfile,也可以指定本地 Dockerfile。

配置的主要目的是解决了手动把 jar 包打包为镜像。

配置

见仓库配置文件 https://github.com/hqweay/blog-backend/blob/master/build.gradle

根目录执行

./gradlew clean build dockerBuilder --info

即可打包。

./gradlew build 这条命令是构建 jar 包。

能看出,整条命令就是先打 jar 包,再执行 dockerBuilder 生成 Dockerfile 文件(或者使用指定的 Dockerfile 文件),再打包为 Docker image。

当然,本地安装了 Docker,就会使用本地 Docker 来完成打包。

如果本地没有 Docker ,idea 可能会自动引入吧。我没试过……

注意

理解打包的这个流程,配置中的各项就很清晰了……照搬配置会出很多问题的……