构建Docker镜像的4种方式
(一)通过Dockerfile对项目的fat jar进行构建
- 创建一个spring-boot项目
为了方便,你可以clone现有的项目来进行练习:
git clone https://github.com/spring-guides/gs-spring-boot-docker.git
cd gs-spring-boot-docker/initial
然后在项目中的src/main/java/hello/Application.java中添加一些简单的功能代码:
package hello;
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;
@SpringBootApplication
@RestController
public class Application {
@RequestMapping("/")
public String home() {
return "Hello Docker World";
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
然后打包项目并启动
./mvnw package && java -jar target/gs-spring-boot-docker-0.1.0.jar
- 容器化项目
在项目的根目录中创建Dockerfile,并添加如下构建代码:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
然后通过Dockerfile来进行镜像构建:
docker build -t lany/gs-spring-boot-docker .
- 启动容器
当镜像构建完成之后,我们可以通过docker images镜像来查看已经制作好的镜像,名称为lany/gs-spring-boot-docker。
现在我们在终端输入以下命令来启动该镜像:
docker run -p 8080:8080 -t lany/gs-spring-boot-docker
访问该项目的接口:
curl -i -XGET 'localhost:8080'
(二) 通过Dockerfile对项目的依赖项以及应用资源进行构建
- 打包项目并对jar包进行资源分离
为了利用Spring Boot fat jar文件中依赖项和应用程序资源的清晰分离,我们可以将依赖项和应用程序打包并构建成镜像。
打包之前的步骤,参考第一章节的创建一个spring-boot项目。
当项目打包完成之后,我们对打包完成的jar包进行分离:
mkdir -p target/dependency && (cd target/dependency;jar -xf ../../target/*.jar)
上一步的命令是在target目录中创建dependency文件夹,然后将分离之后的内容存放到dependency文件夹。
- 将分离后的资源容器化
在项目的根目录创建Dockerfile文件,并添加如下内容:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]
然后通过docker build命令构建镜像:
docker build -t "lany/gs-spring-demo:latest" .
- 启动容器
当镜像构建完成之后,我们可以通过docker images镜像来查看已经制作好的镜像,名称为lany/gs-spring-boot-docker。
现在我们在终端输入以下命令来启动该镜像:
docker run -p 8080:8080 -t lany/gs-spring-boot-docker
访问该项目的接口:
curl -i -XGET 'localhost:8080'
(三) 根据docker-maven-plugin插件来构建docker镜像(免Dockerfile)
除了利用Dockerfile来构建镜像之外,如果你是用maven来构建项目,那么我们还可以用docker-maven-plugin在pom文件中来构建项目镜像。
- 在pom中添加
docker-maven-plugin插件依赖
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.0</version>
<configuration>
<imageName>lany/gs-spring-boot-docker</imageName>
<baseImage>openjdk:8-jdk-alpine</baseImage>
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<!-- copy the service's jar file from target into the root directory of the image -->
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
其中configuration节点的属性在这里解释以下:
imageName:镜像名
imageTags:配置镜像tag,这里指定了两个tag(最新的版本号和latest)
forceTags:强制在每次新的构建上覆盖镜像tags
baseImage:基础镜像
env:配置环境变量
entryPoint:配置执行命令
resources:配置目标jar包的位置
- 构建运行
如果有私有仓库,可以先通过docker login登陆到私有仓库,这样以后就不需要一直登陆了,为上传镜像做准备。
1.指定maven命令进行打包
mvn clean package docker:build
上面这个命令做了打包以及构建镜像的动作。
2.运行容器
当项目镜像构建好了之后,我们可以通过docker run来启动容器:
docker run -p 8080:8080 -t --name dockerbuild lany/gs-spring-boot-docker:latest
访问项目接口:
curl -i -XGET 'localhost:8080'
在pom文件中可以直接指定
baseimage、entrypoint、cmd、maintainer以及resource而不需要单独的Dockerfile。 如果你需要在镜像中指定挂载点(volume)(或者其他docker-maven-plugin不支持的Dockerfile命令),你需要创建一个Dockerfile,并通过dockerDirectory指定Dockerfile文件的所在目录。
(四) 根据docker-maven-plugin插件来构建docker镜像
在上一章节中我们知道可以通过docker-maven-plugin插件免Dockerfile来构建镜像,好处就是可以直接在pom.xml中指定构建命令,确定就是不能支持更多的Dockerfile命令。我们这一章节就来通过docker-maven-plugin插件以及Dockerfile来构建镜像:
- 在pom中添加
docker-maven-plugin插件依赖
1.在项目根目录下创建dockerDir目录,并将Dockerfile添加到该目录下
2.在pom.xml文件中添加docker-maven-plugin插件依赖
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.0</version>
<configuration>
<imageName>lany/gs-spring-boot-docker</imageName>
<imageTags>
<imageTag>${project.version}</imageTag>
</imageTags>
<dockerDirectory>./dockerDir</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
3.在Dockerfile文件中添加如下构建命令
FROM openjdk:8-jdk-alpine
VOLUME /tmp
EXPOSE 8080
ARG JAR_FILE=*.jar
ENV JAVA_OPTS -Xms256m -Xmx256m
ADD ${JAR_FILE} /app.jar
ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom /app.jar"]
- 构建并运行
1.指定maven命令进行打包
mvn clean package docker:build
上面这个命令做了打包以及构建镜像的动作。
2.运行容器
当项目镜像构建好了之后,我们可以通过docker run来启动容器:
docker run -p 8080:8080 -t --name dockerbuild lany/gs-spring-boot-docker:latest
访问项目接口:
curl -i -XGET 'localhost:8080'
(五) 通过dockerfile-maven-plugin插件来构建docker镜像
官方推荐使用dockerfile-maven-plugin来构建docker镜像。
需要注意的是使用该插件构建镜像的要求:
- java7及以后
-
maven3及以上(dockerfile-maven-plugin<=1.4.6 需要maven >=3 ,其他版本需要maven >=3.5.2)
- 在项目根目录中添加
Dockerfile文件,并在Dockerfile文件中添加如下内容:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ENV JAVA_OPTS -Xms256m -Xmx256m
ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom /app.jar"]
ARG JAR_FILE
ADD ${JAR_FILE} /app.jar
- 在pom文件中添加
docker-file-maven依赖
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>library/spring-demo</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
- 构建镜像并运行
1.在这里我们可以省去mvn clean package docker:build这样繁琐的命令,可以直接用mvn clean package来进行打包并构建镜像。
2.运行容器
当项目镜像构建好了之后,我们可以通过docker run来启动容器:
docker run -p 8080:8080 -t --name dockerbuild spring-demo:0.1.0
访问项目接口:
curl -i -XGET 'localhost:8080'
详细文章请参考dockerfile-maven。