有没有办法在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 ...
但它似乎并不是解决手头问题的非常惯用的解决方案。
答案 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)