如何在Docker构建期间强制构建arg?

kon*_*ack 40 docker

是否有任何方法可以在构建期间强制构建参数docker build?如果缺少参数,预期的行为将是构建失败.

例如,对于以下Dockerfile:

FROM ubuntu

ARG MY_VARIABLE
ENV MY_VARIABLE $MY_VARIABLE

RUN ...
Run Code Online (Sandbox Code Playgroud)

我希望构建在构建时失败,并ARG MY_VARIABLE在构建时docker build -t my-tag .传递docker build -t my-tag --build-arg MY_VARIABLE=my_value ..

有没有办法实现这种行为?在我的情况下,设置默认值并不能真正起到作用.

(我跑泊坞窗1.11.1darwin/amd64.)

编辑:我能想到的一种方法是运行一个MY_VARIABLE空的命令,例如:

FROM ubuntu

ARG MY_VARIABLE
RUN test -n "$MY_VARIABLE"
ENV MY_VARIABLE $MY_VARIABLE

RUN ...
Run Code Online (Sandbox Code Playgroud)

但它似乎并不是解决手头问题的非常惯用的解决方案.

小智 31

我用"RUN测试-n"测试了@konradstrack在原始(编辑)帖子中提到的内容......这似乎要求将变量作为docker build命令的构建时间参数传递

FROM ubuntu

ARG MY_VARIABLE
RUN test -n "$MY_VARIABLE"
ENV MY_VARIABLE $MY_VARIABLE
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您确实需要引号,因为 `test -n ` 不会失败,但 `test -n ""` 会失败 (2认同)

Jan*_*ash 18

您还可以使用shell参数扩展来实现此目的.

假设您的强制构建参数被调用 MANDATORY_BUILD_ARGUMENT,并且您希望它被设置为非空,您的Dockerfile可能如下所示:

FROM debian:stretch-slim
MAINTAINER Evel Knievel <evel@kniev.el>

ARG MANDATORY_BUILD_ARGUMENT

RUN \
# Check for mandatory build arguments
    : "${MANDATORY_BUILD_ARGUMENT:?Build argument needs to be set and non-empty.}" \

# Install libraries
&&  apt-get update \
&&  apt-get install -y \
        cowsay \
        fortune \

# Cleanup
&&  apt-get clean \
&&  rm -rf \
        /var/lib/apt/lists/* \
        /var/tmp/* \
        /tmp/* \

CMD ["/bin/bash", "-c", "/usr/games/fortune | /usr/games/cowsay"]
Run Code Online (Sandbox Code Playgroud)

当然,你也希望将build-argument用于某些东西,不像我做的那样,但是,我仍然建议构建这个Dockerfile并将其用于测试运行:)

  • 这不会将参数的值回显给 shell,因此它更适合机密,例如 API 令牌。 (4认同)

joh*_*s85 9

你可以这样做......

 FROM ubuntu:14.04
 ONBUILD ARG MY_VARIABLE
 ONBUILD RUN if [ -z "$MY_VARIABLE" ]; then echo "NOT SET - ERROR"; exit 1; else : ; fi
Run Code Online (Sandbox Code Playgroud)

然后 docker build -t my_variable_base .

然后基于此构建您的图像......

FROM my_variable_base
...
Run Code Online (Sandbox Code Playgroud)

它不是超级干净,但至少它将'bleh'的东西抽象为基本图像.

  • 只有当我删除它时,这在使用`ONBUID`时不起作用. (2认同)

Mac*_*Gol 8

很久以前,我需要引入一个 required (mandatory) ARG,并且为了更好的 UX 在开头包含检查:

FROM ubuntu:bionic
ARG MY_ARG
RUN [ -z "$MY_ARG" ] && echo "MY_ARG is required" && exit 1 || true

...

RUN ./use-my-arg.sh
Run Code Online (Sandbox Code Playgroud)

但这会破坏初始 之后每一层的构建缓存MY_ARG,因为之后的MY_ARG=VALUE每个RUN命令都会被添加。

每当我更改时,MY_ARG它最终都会重建整个映像,而不是RUN仅重新运行最后一个命令。

为了恢复缓存,我将构建更改为多阶段构建:

  • 第一阶段使用MY_ARG并检查它的存在。
  • 第二阶段照常ARG MY_ARG进行,最后宣布正确。
FROM alpine:3.11.5
ARG MY_ARG
RUN [ -z "$MY_ARG" ] && echo "MY_ARG is required" && exit 1 || true

FROM ubuntu:bionic
...
ARG MY_ARG
RUN ./use-my-arg.sh
Run Code Online (Sandbox Code Playgroud)

由于ARG MY_ARG在第二阶段使用之前声明,该阶段的所有先前步骤不受影响,因此可以正确缓存。


mem*_*ero 6

另一个简单的方法:

RUN test -n "$MY_VARIABLE" || (echo "MY_VARIABLE  not set" && false)
Run Code Online (Sandbox Code Playgroud)


Jef*_*Wen 5

我还不能发表评论,因为我没有 50 声望,但我想添加到@Jan Nash 的解决方案中,因为我在使用我的图像时遇到了一些困难。

如果您复制/粘贴@Jan Nash 的解决方案,它将起作用并吐出未指定构建参数的错误消息。

我想添加什么

当我尝试让它在 CentOS 7 映像 (centos:7) 上运行时,Docker 运行该RUN命令而没有出错。

解决方案

确保您使用RUNbash shell执行命令。

RUN ["/bin/bash", "-c", ": ${MYUID:?Build argument needs to be set and not null.}"]

我希望这对未来的人有所帮助。否则,我相信@Jan Nash 的解决方案非常棒。