我使用 docker 来构建我的 Java 应用程序,我使用了多阶段构建,每次运行 docker 命令来构建时都会遇到一些问题 docker 创建带有标签和名称的新中间映像,none我需要调用中间容器的可能性.
那是我的 dockerfile:
FROM jdk8_201-ubuntu16.04 as java_build
RUN apt-get update && \
apt-get install -y dos2unix
ARG MVN_USER
ARG MVN_PASS
ARG GIT_BRANCH
ARG BUILD_ID
ARG COMMIT_ID
WORKDIR /tmp/app
COPY pom.xml /maven-build/pom.xml
COPY /.mvn/settings.xml /maven-build/settings.xml
COPY mvnw ./mvnw
COPY mvnw.cmd ./mvnw.cmd
COPY /.mvn ./.mvn
RUN chmod +x ./mvnw && \
./mvnw -s /maven-build/settings.xml -B -f /maven-build/pom.xml dependency:resolve dependency:resolve-plugins dependency:go-offline
COPY ./ ./
FROM ubuntu
...
Run Code Online (Sandbox Code Playgroud)
在每个运行docker build命令之后,我有很多none图像:
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 30e2325fcf15 18 hours ago 1.68GB
<none> <none> 30e2325fcf16 18 hours ago 1.68GB
<none> <none> 30e2325fcf14 18 hours ago 1.68GB
<none> <none> 30e2325fcf18 18 hours ago 1.68GB
<none> <none> 30e2325fcf13 18 hours ago 1.68GB
Run Code Online (Sandbox Code Playgroud)
如何none将中间图像的名称替换为my_image_name?
mie*_*wid 13
您可以使用--target关键字来构建特定阶段:
docker build --target compile-image --tag compile-image:0.0.1 .
The*_*veO 10
这个 Docker 论坛帖子建议使用标签,如下所示:
\n\n\n对于任何对类似内容感兴趣的人,我\xe2\x80\x99 现在已经找到了\n解决方法。
\n使用
\nLABELdockerfile 中的命令,我向我感兴趣的构建\n阶段添加了一个标签,然后对其进行过滤:Run Code Online (Sandbox Code Playgroud)\nFROM node AS builder-stage\nLABEL builder=true\nRun Code Online (Sandbox Code Playgroud)\nFROM node AS app-stage\nLABEL builder=false\n现在进行过滤,首先对最新的进行排序,删除日期,然后取顶部\n行:
\ndocker images --filter \xe2\x80\x9clabel=builder=true\xe2\x80\x9d --format \xe2\x80\x98{{.CreatedAt}}\\t{{.ID}}\xe2\x80\x99 | sort -nr | head -n 1 | cut -f2请注意,在下一个构建阶段删除标签非常重要。
\n
您可以使用docker build -t image_name 标记<none>图像。但中间图像将作为图像名称。
<none>图像是作为多阶段构建的一部分形成的。如果您的 dockerfile 中有多个 FROM,那么构建镜像将创建多个镜像以及<none>作为主镜像使用的中间镜像的镜像。
例如
码头档案:
$ cat dockerfile
FROM ubuntu:18.04 AS compile-image
RUN apt-get update
RUN apt-get install -y --no-install-recommends gcc build-essential
WORKDIR /root
COPY . hello.c
RUN mkdir -p helloworld hello.c
FROM ubuntu:18.04 AS runtime-image
COPY --from=compile-image /root/helloworld .
CMD ["./helloworld"]
Run Code Online (Sandbox Code Playgroud)
在上面的 dockerfile 中,我使用 ubuntu:18.04 作为中间映像,它在上面的COPY命令中再次使用。这里COPY --from=compile-image /root/helloworld .
因此,当我通过命令使用上述 dockerfile 构建图像时
$ sudo docker build -t sample_image .
Run Code Online (Sandbox Code Playgroud)
上面的命令将创建两个图像,如下所示。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sample_image latest 32b62676d8b8 About a minute ago 64.2MB
<none> <none> dfb370218e54 About a minute ago 282MB
Run Code Online (Sandbox Code Playgroud)
<none>是中间图像。这再次在 dockerfile 内部使用。
现在,您的问题的解决方案是创建两个 docker 文件并分别使用它们。
比如上面的dockerfile可以分成两个dockerfile,可以用来创建独立的镜像,不需要任何中间镜像。
dockerfile 1:
$ sudo vi dockerfile
$ sudo cat dockerfile
FROM ubuntu:18.04 AS compile-image
RUN apt-get update
RUN apt-get install -y --no-install-recommends gcc build-essential
WORKDIR /root
COPY . hello.c
RUN mkdir -p helloworld hello.c
Run Code Online (Sandbox Code Playgroud)
并执行
$ sudo docker build -t compile_image .
通过再次更改docker文件
码头工人文件2:
$ sudo vi dockerfile
$ sudo cat dockerfile
FROM ubuntu:18.04
COPY --from=compile_image /root/helloworld .
CMD ["./helloworld"]
Run Code Online (Sandbox Code Playgroud)
并执行: $ sudo docker build -t runtime_image .
输出不会有中间图像。因此没有<none>图像。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
compile_image latest b580efe23dad About a minute ago 282MB
runtime_image latest 32b62676d8b8 3 minutes ago 64.2MB
Run Code Online (Sandbox Code Playgroud)
仅供参考:在第二个 docker 文件中,我之前在COPY命令中使用了构建映像compile_image
COPY --from=compile_image /root/helloworld .
这里 compile_image 就像一个中间图像。
如果你观察之前的图像,内存占用<none>和 compile_image 是一样的,sample_image 和 runtime_image 是一样的。使用多阶段构建的主要目的是减少图像的大小。
希望这可以帮助。
谢谢。