是否可以根据构建ENV
的值在Dockerfile中有条件地设置ARG
变量?
Ex:类似
ARG BUILDVAR=sad
ENV SOMEVAR=if $BUILDVAR -eq "SO"; then echo "hello"; else echo "world"; fi
更新:根据马里奥的答案当前使用情况:
ARG BUILD_ENV=prod
ENV NODE_ENV=production
RUN if [ "${BUILD_ENV}" = "test" ]; then export NODE_ENV=development; fi
然而,与--build-arg BUILD_ENV=test
一起运行然后进入主机,我仍然得到
docker run -it mycontainer bin/bash
[root@brbqw1231 /]# echo $NODE_ENV
production
答案 0 :(得分:13)
您无法直接在 Dockerfile 中运行bash代码,但必须使用ENV
命令。因此,举例来说,您可以使用RUN
更改if
并导出ARG BUILDVAR=sad
RUN if [ "$BUILDVAR" == "SO"]; \
then export SOMEVAR=hello; \
else export SOMEVAR=world; \
fi
中的变量,如下所示:
{{1}}
我没有尝试,但应该工作。
答案 1 :(得分:13)
是的,有可能,但是您需要使用build参数作为标志。您可以使用外壳程序的parameter expansion功能来检查条件。这是概念验证的Docker文件:
FROM debian:stable
ARG BUILD_DEVELOPMENT
# if --build-arg BUILD_DEVELOPMENT=1, set NODE_ENV to 'development' or set to null otherwise.
ENV NODE_ENV=${BUILD_DEVELOPMENT:+development}
# if NODE_ENV is null, set it to 'production' (or leave as is otherwise).
ENV NODE_ENV=${NODE_ENV:-production}
测试版本:
docker build --rm -t env_prod ./
...
docker run -it env_prod bash
root@2a2c93f80ad3:/# echo $NODE_ENV
production
root@2a2c93f80ad3:/# exit
docker build --rm -t env_dev --build-arg BUILD_DEVELOPMENT=1 ./
...
docker run -it env_dev bash
root@2db6d7931f34:/# echo $NODE_ENV
development
答案 2 :(得分:4)
虽然您无法设置条件ENV
变量,但您可以使用RUN
命令和null-coalescing环境变量来完成您的工作:
RUN node /var/app/current/index.js --env ${BUILD_ENV:-${NODE_ENV:-"development"}}
答案 3 :(得分:3)
你的逻辑实际上是正确的。
这里的问题是RUN export ...
无法在Dockerfile中工作,因为export
命令不会在图像中持续存在。
Dockerfiles创建一个临时容器以便为其生成图像,因此环境变量不会存在。
ENV
:
从生成的图像运行容器时,使用
ENV
设置的环境变量将保持不变。
执行此操作的唯一方法是在从映像生成容器时使用docker run
命令,并将逻辑包装在其中:
if [ "${BUILD_ENV}" = "test" ]; then
docker run -e NODE_ENV=development myimage
else
docker run myimage
fi
答案 4 :(得分:0)
从命令行传递所需的值(TARG)
docker run --env TARG=T1_WS01 -i projects/msbob
然后在你的Dockerfile
中添加类似的内容
Dockerfile:
# if $TARG is not set then "entrypoint" defaults to Q0_WS01
CMD ./entrypoint.sh ${TARG} Q0_WS01
entrypoint.sh
脚本只读取第一个参数
entrypoint.sh:
#!/bin/bash
[ $1 ] || { echo "usage: entrypoint.sh <$TARG>" ; exit ; }
target_env=$1
答案 5 :(得分:0)
如果我们只在谈论环境变量,那么只需在生产环境中进行设置
ENV NODE_ENV prod
在容器启动开发过程中,您可以使用-e NODE_ENV=dev
。
这样,图像始终是内置产品,但是本地容器正在开发中。
答案 6 :(得分:0)
我在容器上设置代理服务器时遇到了类似的问题。
我使用的解决方案是一个入口点脚本和另一个用于环境变量配置的脚本。使用 RUN,您可以确保配置脚本在构建时运行,并在运行容器时运行 ENTRYPOINT。
--build-arg 用于命令行设置代理用户和密码。
入口点脚本如下所示:
#!/bin/bash
# Load the script of environment variables
. /root/configproxy.sh
# Run the main container command
exec "$@"
configproxy.sh
#!/bin/bash
function start_config {
read u p < /root/proxy_credentials
export HTTP_PROXY=http://$u:$p@proxy.com:8080
export HTTPS_PROXY=https://$u:$p@proxy.com:8080
/bin/cat <<EOF > /etc/apt/apt.conf
Acquire::http::proxy "http://$u:$p@proxy.com:8080";
Acquire::https::proxy "https://$u:$p@proxy.com:8080";
EOF
}
if [ -s "/root/proxy_credentials" ]
then
start_config
fi
在 Dockerfile 中,配置:
# Base Image
FROM ubuntu:18.04
ARG user
ARG pass
USER root
# -z the length of STRING is zero
# [] are an alias for test command
# if $user is not empty, write credentials file
RUN if [ ! -z "$user" ]; then echo "${user} ${pass}">/root/proxy_credentials ; fi
#copy bash scripts
COPY configproxy.sh /root
COPY startup.sh .
RUN ["/bin/bash", "-c", ". /root/configproxy.sh"]
# Install dependencies and tools
#RUN apt-get update -y && \
# apt-get install -yqq --no-install-recommends \
# vim iputils-ping
ENTRYPOINT ["./startup.sh"]
CMD ["sh", "-c", "bash"]
无需代理设置即可构建
docker build -t img01 -f Dockerfile .
使用代理设置构建
docker build -t img01 --build-arg user=<USER> --build-arg pass=<PASS> -f Dockerfile .
看看here。
答案 7 :(得分:-1)
如果您仅需要检查是否存在build-arg并且想要设置默认值,那么此answer很好。 为了改进此解决方案,如果要使用build-arg传递的数据,可以执行以下操作:
FROM debian:stable
ARG BUILD_DEVELOPMENT=production
ENV NODE_ENV=$BUILD_DEVELOPMENT
神奇之处在于ARG的默认值。