Docker BuildKit 在使用 Azure DevOps 构建管道将秘密传递给容器时返回“/run/secrets/<secret-id>:没有这样的文件或目录”
Docker BuildKit returning '/run/secrets/<secret-id>: No such file or directory' when passing secrets to container using Azure DevOps build pipeline
我对 docker 和 DevOps 还是很陌生。我正在尝试将一个秘密传递给我的 Docker 容器以在构建中使用。我读到使用 BuildKit 可以提供更高的安全性,因为秘密没有被烘焙到容器中。在按照 post 此处 的底部评论中的步骤进行操作后,我 运行 陷入了问题,这似乎完美地解决了我的问题,而且看起来非常直接和简单,但我不确定怎么了?我可以使用 --build-arg 将其他环境传递到构建中(我没有将它们包含在 yaml 代码片段中),但这种方法似乎在 Dockerfile 阶段对我来说是中断的(我认为).
我的构建管道将值存储为秘密,当我将秘密回显到文件 $(Pipeline.Workspace)/direct_line_secret.txt
并如下所示对其进行分类时,我得到管道构建中返回的 *** 隐藏值作为预期(倒数第二行)。
Starting: Store direct line secret
==============================================================================
Task : Bash
Description : Run a Bash script on macOS, Linux, or Windows
Version : 3.195.0
Author : Microsoft Corporation
Help : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/bash
==============================================================================
Generating script.
========================== Starting Command Output ===========================
/usr/bin/bash /home/vsts/work/_temp/070f6401-2a4d-4656-b674-4fadcce142ea.sh
***
Finishing: Store direct line secret
这是我用于创建此脚本和 docker 构建任务的 yaml 文件。
trigger:
- main
resources:
- repo: self
variables:
dockerfilePath: '$(Build.SourcesDirectory)/Dockerfile'
tag: '$(Build.BuildId)'
DOCKER_BUILDKIT: 1
# Agent VM image name
vmImageName: 'ubuntu-latest'
stages:
- stage: Build
displayName: Build and push stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: $(vmImageName)
variables:
DOCKER_BUILDKIT: 1
steps:
- bash: |
echo ${DIRECT_LINE_SECRET} > $SECRET
cat $SECRET
displayName: Store direct line secret
env:
DIRECT_LINE_SECRET: $(nextPublicDirectLineSecret)
SECRET: $(Pipeline.Workspace)/direct_line_secret.txt
- task: Docker@2
displayName: Build image
inputs:
command: build
repository: $(imageRepository)
dockerfile: $(dockerfilePath)
containerRegistry: $(dockerRegistryServiceConnection)
arguments: --secret id=dl_secret,src=$(Pipeline.Workspace)/direct_line_secret.txt --build-arg [...]
tags: |
$(tag)
[...]
这是我的Docker文件
# Build target base #
#####################
FROM node:lts-alpine AS base
WORKDIR /app
ARG NODE_ENV=production \
API_BASE \
SIGNALR_BASE \
DIRECT_LINE_SECRET
ENV PATH=/app/node_modules/.bin:$PATH \
NODE_ENV="$NODE_ENV" \
NEXT_PUBLIC_API_BASE_URL=$API_BASE \
NEXT_PUBLIC_SIGNALR_BASE_URL=$SIGNALR_BASE
RUN apk --no-cache add curl
COPY package.json yarn.lock /app/
EXPOSE 3000
# Build target dependencies #
#############################
FROM base AS dependencies
# Install prod dependencies
RUN yarn install --production && \
# Cache prod dependencies
cp -R node_modules /prod_node_modules && \
# Install dev dependencies
yarn install --production=false
# Build target development #
############################
FROM dependencies AS development
COPY . /app
CMD [ "yarn", "dev" ]
# Build target builder #
########################
FROM base AS builder
COPY --from=dependencies /app/node_modules /app/node_modules
COPY . /app
RUN --mount=type=secret,id=dl_secret
RUN export NEXT_PUBLIC_DIRECT_LINE_SECRET=$(cat /run/secrets/dl_secret)
RUN yarn build && \
rm -rf node_modules
# Build target production #
###########################
FROM base AS production
COPY --from=builder /app/public /app/public
COPY --from=builder /app/.next /app/.next
COPY --from=builder /app/next.config.js /app/next.config.js
COPY --from=dependencies /prod_node_modules /app/node_modules
CMD [ "yarn", "start" ]
HEALTHCHECK --interval=5s --timeout=5s --retries=3 \
CMD curl --fail http://localhost:3000 || exit 1
我最初将这两行放在顶部 运行 行的下面,但我想也许它们被调用得太早了?向下移动时我仍然遇到同样的问题...
RUN --mount=type=secret,id=dl_secret
RUN export NEXT_PUBLIC_DIRECT_LINE_SECRET=$(cat /run/secrets/dl_secret)
这是我在 docker 构建任务
的构建管道中遇到的错误
[...]
#12 [builder 3/5] RUN --mount=type=secret,id=dl_secret
#12 sha256:8a1115368ff855c4abf1043ef21d89bc00cfaa8759ba13fc73644e5df74a668b
#12 DONE 0.3s
#13 [builder 4/5] RUN export NEXT_PUBLIC_DIRECT_LINE_SECRET=$(cat /run/secrets/dl_secret)
#13 sha256:0e752980cf8a0ad0065c0ecc815a4f42a9c06aff4dc6de47eef68b9f01805e96
#13 0.306 cat: can't open '/run/secrets/dl_secret': No such file or directory
#13 DONE 0.3s
[...]
阅读 BuildKit 文档时,它说 运行 docker 像这样构建 DOCKER_BUILDKIT=1 docker build
,或者设置变量,如 post 我在上面链接了我已经完成的(我什至设置了两次以确保它没有在错误的地方)但这是我的 docker 命令在查看这些管道构建日志时的样子
/usr/bin/docker build -f /home/vsts/work/1/s/Dockerfile --label com.azure.dev.image.system.teamfoundationcollectionuri=https://dev.azure.com/[...]
它是否应该在构建命令前面有 DOCKER_BUILDKIT=1
我不知道,这可能是它不起作用的原因吗?
我不确定构建有什么问题,是没有创建文件的情况,还是我设置错误?我花了几个小时试图研究这个问题,但没有找到太多适用的信息,并且进行了 100 次编辑都无济于事。也许这是相当简单的事情,但我真的很急于在这个周末对它进行排序,我不确定下一步该尝试什么。我不确定如何浏览 DevOps 上的文件以查看是否有任何文件。
如有任何帮助,我们将不胜感激!
--mount
命令必须在您希望使用您的秘密的同一层中使用。您目前正在一个 RUN
命令中指定 --mount
,然后试图 cat
在另一个 RUN
命令中安装的秘密。
如果您将 Dockerfile 更改为使用单个 RUN
命令,则安装的秘密将可用:
RUN --mount=type=secret,id=dl_secret \
export NEXT_PUBLIC_DIRECT_LINE_SECRET=$(cat /run/secrets/dl_secret)
Dockerfile 前端的当前语法可以在这里找到:https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md#run---mounttypesecret
我对 docker 和 DevOps 还是很陌生。我正在尝试将一个秘密传递给我的 Docker 容器以在构建中使用。我读到使用 BuildKit 可以提供更高的安全性,因为秘密没有被烘焙到容器中。在按照 post 此处
我的构建管道将值存储为秘密,当我将秘密回显到文件 $(Pipeline.Workspace)/direct_line_secret.txt
并如下所示对其进行分类时,我得到管道构建中返回的 *** 隐藏值作为预期(倒数第二行)。
Starting: Store direct line secret
==============================================================================
Task : Bash
Description : Run a Bash script on macOS, Linux, or Windows
Version : 3.195.0
Author : Microsoft Corporation
Help : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/bash
==============================================================================
Generating script.
========================== Starting Command Output ===========================
/usr/bin/bash /home/vsts/work/_temp/070f6401-2a4d-4656-b674-4fadcce142ea.sh
***
Finishing: Store direct line secret
这是我用于创建此脚本和 docker 构建任务的 yaml 文件。
trigger:
- main
resources:
- repo: self
variables:
dockerfilePath: '$(Build.SourcesDirectory)/Dockerfile'
tag: '$(Build.BuildId)'
DOCKER_BUILDKIT: 1
# Agent VM image name
vmImageName: 'ubuntu-latest'
stages:
- stage: Build
displayName: Build and push stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: $(vmImageName)
variables:
DOCKER_BUILDKIT: 1
steps:
- bash: |
echo ${DIRECT_LINE_SECRET} > $SECRET
cat $SECRET
displayName: Store direct line secret
env:
DIRECT_LINE_SECRET: $(nextPublicDirectLineSecret)
SECRET: $(Pipeline.Workspace)/direct_line_secret.txt
- task: Docker@2
displayName: Build image
inputs:
command: build
repository: $(imageRepository)
dockerfile: $(dockerfilePath)
containerRegistry: $(dockerRegistryServiceConnection)
arguments: --secret id=dl_secret,src=$(Pipeline.Workspace)/direct_line_secret.txt --build-arg [...]
tags: |
$(tag)
[...]
这是我的Docker文件
# Build target base #
#####################
FROM node:lts-alpine AS base
WORKDIR /app
ARG NODE_ENV=production \
API_BASE \
SIGNALR_BASE \
DIRECT_LINE_SECRET
ENV PATH=/app/node_modules/.bin:$PATH \
NODE_ENV="$NODE_ENV" \
NEXT_PUBLIC_API_BASE_URL=$API_BASE \
NEXT_PUBLIC_SIGNALR_BASE_URL=$SIGNALR_BASE
RUN apk --no-cache add curl
COPY package.json yarn.lock /app/
EXPOSE 3000
# Build target dependencies #
#############################
FROM base AS dependencies
# Install prod dependencies
RUN yarn install --production && \
# Cache prod dependencies
cp -R node_modules /prod_node_modules && \
# Install dev dependencies
yarn install --production=false
# Build target development #
############################
FROM dependencies AS development
COPY . /app
CMD [ "yarn", "dev" ]
# Build target builder #
########################
FROM base AS builder
COPY --from=dependencies /app/node_modules /app/node_modules
COPY . /app
RUN --mount=type=secret,id=dl_secret
RUN export NEXT_PUBLIC_DIRECT_LINE_SECRET=$(cat /run/secrets/dl_secret)
RUN yarn build && \
rm -rf node_modules
# Build target production #
###########################
FROM base AS production
COPY --from=builder /app/public /app/public
COPY --from=builder /app/.next /app/.next
COPY --from=builder /app/next.config.js /app/next.config.js
COPY --from=dependencies /prod_node_modules /app/node_modules
CMD [ "yarn", "start" ]
HEALTHCHECK --interval=5s --timeout=5s --retries=3 \
CMD curl --fail http://localhost:3000 || exit 1
我最初将这两行放在顶部 运行 行的下面,但我想也许它们被调用得太早了?向下移动时我仍然遇到同样的问题...
RUN --mount=type=secret,id=dl_secret
RUN export NEXT_PUBLIC_DIRECT_LINE_SECRET=$(cat /run/secrets/dl_secret)
这是我在 docker 构建任务
的构建管道中遇到的错误[...]
#12 [builder 3/5] RUN --mount=type=secret,id=dl_secret
#12 sha256:8a1115368ff855c4abf1043ef21d89bc00cfaa8759ba13fc73644e5df74a668b
#12 DONE 0.3s
#13 [builder 4/5] RUN export NEXT_PUBLIC_DIRECT_LINE_SECRET=$(cat /run/secrets/dl_secret)
#13 sha256:0e752980cf8a0ad0065c0ecc815a4f42a9c06aff4dc6de47eef68b9f01805e96
#13 0.306 cat: can't open '/run/secrets/dl_secret': No such file or directory
#13 DONE 0.3s
[...]
阅读 BuildKit 文档时,它说 运行 docker 像这样构建 DOCKER_BUILDKIT=1 docker build
,或者设置变量,如 post 我在上面链接了我已经完成的(我什至设置了两次以确保它没有在错误的地方)但这是我的 docker 命令在查看这些管道构建日志时的样子
/usr/bin/docker build -f /home/vsts/work/1/s/Dockerfile --label com.azure.dev.image.system.teamfoundationcollectionuri=https://dev.azure.com/[...]
它是否应该在构建命令前面有 DOCKER_BUILDKIT=1
我不知道,这可能是它不起作用的原因吗?
我不确定构建有什么问题,是没有创建文件的情况,还是我设置错误?我花了几个小时试图研究这个问题,但没有找到太多适用的信息,并且进行了 100 次编辑都无济于事。也许这是相当简单的事情,但我真的很急于在这个周末对它进行排序,我不确定下一步该尝试什么。我不确定如何浏览 DevOps 上的文件以查看是否有任何文件。
如有任何帮助,我们将不胜感激!
--mount
命令必须在您希望使用您的秘密的同一层中使用。您目前正在一个 RUN
命令中指定 --mount
,然后试图 cat
在另一个 RUN
命令中安装的秘密。
如果您将 Dockerfile 更改为使用单个 RUN
命令,则安装的秘密将可用:
RUN --mount=type=secret,id=dl_secret \
export NEXT_PUBLIC_DIRECT_LINE_SECRET=$(cat /run/secrets/dl_secret)
Dockerfile 前端的当前语法可以在这里找到:https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md#run---mounttypesecret