共计 3519 个字符,预计需要花费 9 分钟才能阅读完成。
想必 Docker
这个词大家都不生疏,是一个十分优良的虚拟化容器。
我的博客
怎么把 Java
利用打包成 Docker 镜像?对相熟 Docker
的同学这应该是一个很简略的问题,把我的项目打包成 JAR
包而后在 Dockerfile
里用 ADD
命令把 JAR
文件放到镜像里,启动命令设置执行这个 JAR
文件即可。
可是对于不懂 Java 的,听起来貌似并不是那么简略。
在这之前,咱们先理解理解什么是:Dockerfile
。
Dockerfile
Dockerfile
是一个用来构建镜像的文本文件,文本内容蕴含了一条条构建镜像所需的指令和阐明。
比方一个应用 Maven 构建的 Spring 利用就能够用上面这个 Dockerfile
构建镜像。
FROM openjdk:8-jre
ADD target/*.jar /application.jar
ENTRYPOINT ["java", "-jar","/application.jar"]
咦?这是啥语言,也没见过啊?这个其实是 dockerfile
的指令。
下面这个 Dockerfile
的指令很好了解,应用 Maven 构建的 Java 我的项目的目录构造对立是:
project
│ pom.xml
└───src // 源文件目录
│ │
│ └───main
│ │
│ └───java
│
└───target // class 和 jar 文件的目录
用 mvn clean package
打包后会把 JAR
文件生成在 target
目录里,通过 java -jar
命令即可执行编译好的程序。
所以下面的 Dockerfile
里就进行了把 JAR
从target
目录里增加到 Docker 镜像中以及将jar -jar /application.jar
设置成容器的启动命令这两步操作。
不过除了这种最原始的办法外咱们还能够应用 Maven
的一些插件,或者 Docker
的多阶段打包性能来实现把 Java
利用打包成 Docker
镜像的动作。
Maven 插件构建镜像
Spotify
公司的 dockerfile-maven-plugin
和 Google 公司出品的 jib-maven-plugin
是两款比拟有名的插件,上面简略介绍一下 dockerfile-maven-plugin
的配置和应用。
其实应用办法很简略,咱们在 POM
文件里引入这个 plugin
,并联合下面那个Dockerfile
就能让插件帮忙咱们实现利用镜像的打包。
<groupId>com.example</groupId>
<artifactId>hello-spring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>helloworld</name>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.10</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>${docker.registry.url}/${image.prefix}/${artifactId}</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
插件里应用的 docker.registry.url
和image.prefix
是我独自为 Docker
的镜像仓库设置的属性。
<properties>
<java.version>1.8</java.version>
<image.prefix>kevinyan001</image.prefix>
<docker.registry.url></private.registry.url>
</properties>
这里能够随便设置成公有仓库的近程地址和镜像前缀,比方在阿里云的镜像服务上创立一个叫 docker-demo
的空间,下面的属性就须要这样配置:
<properties>
<java.version>1.8</java.version>
<image.prefix>docker-demo</image.prefix>
<docker.registry.url>registry.cn-beijing.aliyuncs.com</docker.registry.url>
</properties>
在 POM
文件里配置好插件后随同着咱们打包利用执行 mvc clean package
操作时 dockerfile-maven-plugin
就会主动依据咱们的配置打包好一个叫做 kevinyan001/hello-spring:0.0.1-SNAPSHOT
的 Docker 镜像。
dockerfile-maven-plugin
除了能帮忙咱们打包利用镜像外还能够让它帮忙咱们把镜像 push 到远端仓库,不过我感觉用途不大,感兴趣的同学能够去网上搜搜看这部分性能怎么配置。
Docker 的多阶段构建打包镜像
下面介绍了应用 Maven
插件帮忙咱们打包 Java
利用的镜像,其实咱们还能够把 mvn clean package
这一步也交给 Docker
来实现。当然把 Java 利用的源码放在 Docker
镜像里再编译打包在公布进来必定是有问题的,咱们晓得在 Dockerfile
里每个指令 ADD
、RUN
这些都是在独自的层上进行,指令越多会造成镜像越大,而且蕴含 Java
我的项目的源码也是一种危险。
不过好在起初 Docker
反对了多阶段构建,容许咱们在一个 Dockerfile
里定义多个构建阶段,先拉起一个容器实现用于的构建,比如说咱们能够在这个阶段里实现 JAR
的打包,而后第二个阶段从新应用一个 jre
镜像把上阶段打包好的 JAR
文件拷贝到新的镜像里。
应用上面的 Dockerfile
能够通过多阶段构建实现 Java
利用的 Docker
镜像打包。
# Dockerfile 也能够不放在我的项目目录下,通过 -f 指定 Dockerfile 的地位,比方在我的项目根下执行以下命令
docker build -t <some tag> -f <dirPath/Dockerfile> .
FROM kevinyan001/aliyun-mvn:0.0.1 AS MAVEN_BUILD
COPY pom.xml /build/
COPY src /build/src
WORKDIR /build/
# mount anonymous host directory as .m2 storage for contianer
VOLUME /root/.m2
RUN mvn clean package -Dmaven.test.skip=true --quiet
FROM openjdk:8-jre
COPY --from=MAVEN_BUILD /build/target/*.jar /app/application.jar
ENTRYPOINT ["java", "-jar", "/app/application.jar"]
下面咱们用的这些 Dockerfile
也能够不必放在我的项目的根目录里,当初曾经反对通过 -f
指定 Dockerfile
的地位,比方在我的项目根下执行以下命令实现镜像的打包。
docker build -t kevinyan001/hello-spring:0.0.1 -f <dirPath/Dockerfile> .
下面第一个镜像是我本人做的,因为 Maven 官网的镜像的近程仓库慢的一批,只能本人包装一下走阿里云的镜像源了。试了试速度也不快,次要是随随便便一个 Spring
我的项目依赖就太多了。大家如果这块有什么放慢Docker
构建速度的办法也能够留言一起探讨探讨。
不可否认用多阶段构建打进去的 Go
镜像基本上是 10M
左右,然而 Spring
的利用随随便便就是上百兆,这个对容器的构建速度、网络传输老本是有影响的,那么 Spring
利用的镜像怎么瘦身呢,这个就留到当前的文章进行探讨了。