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

时间:2016-07-18 14:11:32

标签: docker

有没有办法在docker build期间强制构建参数?如果缺少参数,预期的行为将是构建失败。

例如,对于以下Dockerfile:

FROM ubuntu

ARG MY_VARIABLE
ENV MY_VARIABLE $MY_VARIABLE

RUN ...

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

有没有办法实现这种行为?在我的情况下,设置默认值并不能解决问题。

(我在1.11.1上运行了Docker darwin/amd64。)

修改: 我能想到的一种方法是运行MY_VARIABLE为空时失败的命令,例如:

FROM ubuntu

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

RUN ...

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

6 个答案:

答案 0 :(得分:24)

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

FROM ubuntu

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

答案 1 :(得分:16)

您也可以使用shell parameter expansion来实现此目的。

假设您的强制构建参数名为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"]

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

答案 2 :(得分:8)

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

 FROM ubuntu:14.04
 ONBUILD ARG MY_VARIABLE
 ONBUILD RUN if [ -z "$MY_VARIABLE" ]; then echo "NOT SET - ERROR"; exit 1; else : ; fi

然后docker build -t my_variable_base .

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

FROM my_variable_base
...

它不是超级干净,但至少它抽象了&#39; bleh&#39;东西到基础图像。

答案 3 :(得分:6)

很久以前,我需要引入必需的(强制性的)ARG,为了获得更好的用户体验,请在开头添加检查:

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

...

RUN ./use-my-arg.sh

但是这会在初始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

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

答案 4 :(得分:4)

我还没有评论,因为我没有50个声誉,但是我想添加到@Jan Nash的解决方案中,因为我很难使它与我的图像配合使用。

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

我要添加的内容

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

解决方案

确保您正在使用bash shell执行RUN命令。

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

我希望这对将来的来访者有所帮助。否则,我相信@Jan Nash的解决方案非常出色。

答案 5 :(得分:1)

另一种简单方法:

RUN test -n "$MY_VARIABLE" || (echo "MY_VARIABLE  not set" && false)