我做了一些搜索,但docker
CLI 目前似乎没有提供任何直接的方法来做到这一点。最接近的是我在评论中提出的想法:构建主图像并标记所有中间图像。
以此Dockerfile
为例:
FROM alpine AS frontend
RUN sleep 15 && touch /frontend
FROM alpine AS backend
RUN sleep 15 && touch /backend
FROM alpine AS runtime
COPY --from=frontend /frontend /frontend
COPY --from=backend /backend /backend
(这些sleep
s 只是为了通过缓存明显加快速度)
建立这个:
export DOCKER_BUILDKIT=1 # enable buildkit for parallel builds
docker build -t my-project .
docker build -t my-project-backend --target backend .
docker build -t my-project-frontend --target frontend .
将要
runtime
通过首先构建所有必需的中间图像来构建主图像,例如frontend
和,并且只用backend
标记主图像my-project
- 构建
backend
标记为my-project-backend
但使用先前构建中的缓存的目标
- 一样,但对于
backend
这里的每个图像只会构建一次 - 但最终这与您在问题中所述所做的完全相同,只是顺序不同。
如果您真的希望能够在单个命令中执行此操作,您可以使用它docker-compose
来构建“多个图像”:
version: "3.8"
services:
my-project:
image: my-project
build: .
backend:
image: my-project-backend
build:
context: .
target: backend
frontend:
image: my-project-frontend
build:
context: .
target: frontend
export DOCKER_BUILDKIT=1 # enable buildkit for parallel builds
export COMPOSE_DOCKER_CLI_BUILD=1 # use docker cli for building
docker-compose build
这里docker-compose
基本上会docker build
为你运行与上面相同的命令。
在这两种情况下,尽管您应该知道,尽管缓存层大大加快了构建速度,但仍然会发生新的构建,每次都会:
- 将构建上下文(即当前目录的内容)发送到 docker 守护进程
- 将您的任何远程文件下载
ADD
到图像中,并且仅在内容再次相同时才使用缓存-对于大文件/慢速网络,这将显着减慢。
我在这个论坛帖子中发现的另一个解决方法是在图像中添加一个LABEL
并用于docker image ls --filter
在构建后获取图像 ID。
但是测试它似乎docker image ls
不会在使用时显示中间图像buildkit
。此外,这种方法将需要更多命令/专用脚本 - 这将再次比您当前的方法更多工作。