多阶段 dockerfile 跳过阶段

Nik*_*pta 8 docker dockerfile docker-multi-stage-build

我正在尝试构建一个具有以下阶段的多阶段 dockerfile,但所有阶段都在执行。

即使我EXECUTION_ENV=local在 docker 构建中指定了,我总是认为 git clone 正在执行

Dockerfile:

ARG GIT_TOKEN=abc:1a2b3
ARG EXECUTION_ENV=local

# get dependencies from github
FROM alpine/git as gitclone-ci
WORKDIR /usr/src/
RUN git clone https://{GIT_USER_TOKEN}@github.com/something.git \
    && git clone https://{GIT_USER_TOKEN}@github.com/somethingelse.git

## in local dependencies are already available in the parent folder
FROM alpine/git as gitclone-local
WORKDIR /usr/src/
COPY ../something /usr/src/something 
COPY ../somethingelse /usr/src/somethingelse

FROM node:latest as builder
WORKDIR /usr/src
COPY --from=gitclone-${EXECUTION_ENV} /usr/src .
COPY package* ./
COPY src/ src/
RUN ["npm", "install"]
Run Code Online (Sandbox Code Playgroud)

Docker 构建命令尝试:

docker build -t somecontainer --build-arg GIT_TOKEN=abc:123 --build-arg EXECUTION_ENV=local.

docker build -t somecontainer --target builder --build-arg GIT_TOKEN=abc:123 --build-arg EXECUTION_ENV=local.
Run Code Online (Sandbox Code Playgroud)

注意: 如果我在 docker 守护进程中启用"features": { "buildkit": true}并运行 cmd,docker build -t somecontainer --build-arg GIT_TOKEN=abc:123 --build-arg EXECUTION_ENV=local.我会收到以下错误

failed to solve with frontend dockerfile.v0: failed to create LLB definition: failed to parse stage name "gitclone-$EXECUTION_ENV": invalid reference format: repository name must be lowercase
Run Code Online (Sandbox Code Playgroud)

Kon*_*tor 10

跳过阶段仅适用于 BuildKit。请参阅此处的讨论和此处的文章。

至于您收到的错误,您应该在使用或不使用 BuildKit 的情况下得到它,因为您不能在COPY指令中使用构建参数。不同之处在于,使用 BuildKit Docker 甚至会拒绝启动构建,如果没有它,构建将在COPY指令上失败。

FROM您需要做的是使用指令解析构建参数这一事实,为要从中复制的图像创建一个附加别名:

ARG GIT_TOKEN=abc:1a2b3
ARG EXECUTION_ENV=local

# get dependencies from github
FROM alpine/git as gitclone-ci
WORKDIR /usr/src/
RUN git clone https://{GIT_USER_TOKEN}@github.com/something.git \
    && git clone https://{GIT_USER_TOKEN}@github.com/somethingelse.git

## in local dependencies are already available in the parent folder
FROM alpine/git as gitclone-local
WORKDIR /usr/src/
COPY ../something /usr/src/something 
COPY ../somethingelse /usr/src/somethingelse

FROM gitclone-${EXECUTION_ENV} as intermediate

FROM node:latest as builder
WORKDIR /usr/src
COPY --from=intermediate /usr/src .
COPY package* ./
COPY src/ src/
RUN ["npm", "install"]
Run Code Online (Sandbox Code Playgroud)