我有dockerfile
FROM centos:7
ENV foo=42
然后我建立它
docker build -t my_docker .
然后运行它。
docker run -it -d my_docker
是否可以从命令行传递参数,并在Dockerfile中使用if else ?我的意思是
FROM centos:7
if (my_arg==42)
{ENV=TRUE}
else:
{ENV=FALSE}
用这个论证来构建。
docker build -t my_docker . --my_arg=42
对于上述提出的解决方案,有一个有趣的替代方案,它使用单个Dockerfile,每个条件构建只需要调用一次docker构建,并避免bash。
解决方案:
下面的Dockerfile解决了这个问题。复制粘贴,自己试试。
ARG my_arg
FROM centos:7 AS base
RUN echo "do stuff with the centos image"
FROM base AS branch-version-1
RUN echo "this is the stage that sets VAR=TRUE"
ENV VAR=TRUE
FROM base AS branch-version-2
RUN echo "this is the stage that sets VAR=FALSE"
ENV VAR=FALSE
FROM branch-version-${my_arg} AS final
RUN echo "VAR is equal to ${VAR}"
Dockerfile说明:
我们首先得到一个基本图像(在您的例子中是centos:7),并将其放入自己的阶段。基本阶段应该包含在条件之前要做的事情。在那之后,我们还有两个阶段,代表我们的条件的分支:branch-version-1和branch-version-2。我们两个都做了。最终阶段根据my_arg选择其中一个阶段。条件Dockerfile。好了。
运行时输出:
(我把它缩写了一下…)
my_arg = = 2
docker build --build-arg my_arg=2 .
Step 1/12 : ARG my_arg
Step 2/12 : ARG ENV
Step 3/12 : FROM centos:7 AS base
Step 4/12 : RUN echo "do stuff with the centos image"
do stuff with the centos image
Step 5/12 : FROM base AS branch-version-1
Step 6/12 : RUN echo "this is the stage that sets VAR=TRUE"
this is the stage that sets VAR=TRUE
Step 7/12 : ENV VAR=TRUE
Step 8/12 : FROM base AS branch-version-2
Step 9/12 : RUN echo "this is the stage that sets VAR=FALSE"
this is the stage that sets VAR=FALSE
Step 10/12 : ENV VAR=FALSE
Step 11/12 : FROM branch-version-${my_arg}
Step 12/12 : RUN echo "VAR is equal to ${VAR}"
VAR is equal to FALSE
my_arg = = 1
docker build --build-arg my_arg=1 .
...
Step 11/12 : FROM branch-version-${my_arg}
Step 12/12 : RUN echo "VAR is equal to ${VAR}"
VAR is equal to TRUE
感谢Tõnis提供这个惊人的想法!
我在容器上设置代理服务器时遇到了类似的问题。
我使用的解决方案是一个入口点脚本和另一个环境变量配置脚本。使用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 .
看看这里。
使用Bash脚本和Alpine/Centos
Dockerfile
FROM alpine #just change this to centos
ARG MYARG=""
ENV E_MYARG=$MYARG
ADD . /tmp
RUN chmod +x /tmp/script.sh && /tmp/script.sh
script.sh
#!/usr/bin/env sh
if [ -z "$E_MYARG" ]; then
echo "NO PARAM PASSED"
else
echo $E_MYARG
fi
传递参数:
docker build -t test——build-arg MYARG="this is a test"。
....
Step 5/5 : RUN chmod +x /tmp/script.sh && /tmp/script.sh
---> Running in 10b0e07e33fc
this is a test
Removing intermediate container 10b0e07e33fc
---> f6f085ffb284
Successfully built f6f085ffb284
无参数:
Docker build -t test。
....
Step 5/5 : RUN chmod +x /tmp/script.sh && /tmp/script.sh
---> Running in b89210b0cac0
NO PARAM PASSED
Removing intermediate container b89210b0cac0
....