nic*_*bpe 86 docker dockerfile
我有dockerfile
FROM centos:7
ENV foo=42
Run Code Online (Sandbox Code Playgroud)
然后我建立它
docker build -t my_docker .
Run Code Online (Sandbox Code Playgroud)
并运行它.
docker run -it -d my_docker
Run Code Online (Sandbox Code Playgroud)
是否可以从命令行传递参数并在Dockerfile中使用if else?我的意思是
FROM centos:7
if (my_arg==42)
{ENV=TRUE}
else:
{ENV=FALSE}
Run Code Online (Sandbox Code Playgroud)
并使用此参数构建.
docker build -t my_docker . --my_arg=42
Run Code Online (Sandbox Code Playgroud)
Qas*_*raz 141
它可能看起来不干净但你可以拥有你的Dockerfile(有条件的)如下:
FROM centos:7
ARG arg
RUN if [ "x$arg" = "x" ] ; then echo Argument not provided ; else echo Argument is $arg ; fi
Run Code Online (Sandbox Code Playgroud)
然后将图像构建为:
docker build -t my_docker . --build-arg arg=45
要么
docker build -t my_docker .
Use*_*645 112
所提出的解决方案有一个有趣的替代方案,它适用于单个 Dockerfile,每个条件构建只需要一次调用docker build 并避免 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}"
Run Code Online (Sandbox Code Playgroud)
Dockerfile 说明:
我们首先获得一个base图像(centos:7在您的情况下)并将其放入自己的舞台。该base阶段应包含所需的条件之前做的事情。之后,我们还有两个阶段,代表我们条件的分支:branch-version-1和branch-version-2。我们构建了它们。final阶段然后根据选择这些阶段之一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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
bar*_*rat 18
根据build命令文档,有一个名为的参数--build-arg
https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables-build-arg
用法示例
docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 .
IMO这是你需要的:)
Luc*_*tto 15
该接受的答案可以解决问题的,但如果你想多if在dockerfile的条件下,你可以做到这一点放置\在每行的末尾(类似于你将如何在shell脚本做),并结束与每个命令;。您甚至可以将类似的内容定义set -eux为第一个命令。
例子:
RUN set -eux; \
if [ -f /path/to/file ]; then \
mv /path/to/file /dest; \
fi; \
if [ -d /path/to/dir ]; then \
mv /path/to/dir /dest; \
fi
Run Code Online (Sandbox Code Playgroud)
在你的情况下:
FROM centos:7
ARG arg
RUN if [ -z "$arg" ] ; then \
echo Argument not provided; \
else \
echo Argument is $arg; \
fi
Run Code Online (Sandbox Code Playgroud)
然后构建:
docker build -t my_docker . --build-arg arg=42
Run Code Online (Sandbox Code Playgroud)
dsa*_*don 12
由于某种原因,这里的大多数答案都没有帮助我(也许它与我在Dockerfile中的FROM图像有关)
所以我更喜欢bash script在我的工作空间中创建一个结合,--build-arg以便在Docker构建时通过检查参数是否为空来处理if语句
Bash脚本:
#!/bin/bash -x
if test -z $1 ; then
echo "The arg is empty"
....do something....
else
echo "The arg is not empty: $1"
....do something else....
fi
Run Code Online (Sandbox Code Playgroud)
Dockerfile:
FROM ...
....
ARG arg
COPY bash.sh /tmp/
RUN chmod u+x /tmp/bash.sh && /tmp/bash.sh $arg
....
Run Code Online (Sandbox Code Playgroud)
Docker构建:
docker build --pull -f "Dockerfile" -t $SERVICE_NAME --build-arg arg="yes" .
Run Code Online (Sandbox Code Playgroud)
备注:这将转到bash脚本中的else(false)
docker build --pull -f "Dockerfile" -t $SERVICE_NAME .
Run Code Online (Sandbox Code Playgroud)
备注:这将转到if(true)
编辑1:
几次尝试之后,我发现下面的文章,这一个 这让我明白两两件事:
1)FROM之前的ARG在构建之外
2)默认的shell是/ bin/sh,这意味着在docker构建中if else的工作方式有点不同.例如,您只需要一个"="而不是"=="来比较字符串.
所以你可以在里面做到这一点 Dockerfile
ARG argname=false #default argument when not provided in the --build-arg
RUN if [ "$argname" = "false" ] ; then echo 'false'; else echo 'true'; fi
Run Code Online (Sandbox Code Playgroud)
并在docker build:
docker build --pull -f "Dockerfile" --label "service_name=${SERVICE_NAME}" -t $SERVICE_NAME --build-arg argname=true .
Run Code Online (Sandbox Code Playgroud)
Dav*_*ave 12
尽可能不要使用其他答案中描述的构建参数。这是一个旧的混乱解决方案。Docker 的 target 属性解决了这个问题。
文件
FROM foo as base
RUN ...
# Build dev image
FROM base as image-dev
RUN ...
COPY ...
# Build prod image
FROM base as image-prod
RUN ...
COPY ...
Run Code Online (Sandbox Code Playgroud)
docker build --target image-dev -t foo .
Run Code Online (Sandbox Code Playgroud)
docker build --target image-dev -t foo .
Run Code Online (Sandbox Code Playgroud)
Dockerfiles 在现实世界中变得复杂。使用 buildkit © --from来获得更快、更易于维护的 Dockerfile:
COPY --from以简化继承。version: '3.4'
services:
dev:
build:
context: .
dockerfile: Dockerfile
target: image-dev
Run Code Online (Sandbox Code Playgroud)
启用实验模式。
sudo echo '{"experimental": true}' | sudo tee /etc/docker/daemon.json
Run Code Online (Sandbox Code Playgroud)
在启用 buildkit 的情况下构建。默认情况下,Buildkit 在没有缓存的情况下构建 - 启用--build-arg BUILDKIT_INLINE_CACHE=1
CI 构建工作。
DOCKER_BUILDKIT=1 \
docker build \
--build-arg BUILDKIT_INLINE_CACHE=1 \
--target image-ci\
-t foo:ci
.
Run Code Online (Sandbox Code Playgroud)
使用来自拉取图像的缓存 --cache-from
产品构建工作
docker pull foo:ci
docker pull foo:stage
DOCKER_BUILDKIT=1 \
docker build \
--cache-from foo:ci,foo:stage \
--target image-dev \
-t prod
.
Run Code Online (Sandbox Code Playgroud)
小智 11
只需直接使用"test"二进制文件即可.如果您不想指定"else"条件,也应该使用noop命令":",因此docker不会因非零返回值错误而停止.
RUN test -z "$YOURVAR" || echo "var is set" && echo "var is not set"
RUN test -z "$YOURVAR" && echo "var is not set" || :
RUN test -z "$YOURVAR" || echo "var is set" && :
Run Code Online (Sandbox Code Playgroud)
正如其他人所说,shell 脚本会有所帮助。
只是一个额外的案例,恕我直言,值得一提(对于在这里偶然发现的其他人,寻找一个更简单的案例),那就是Environment replacement。
环境变量(用
ENV语句声明)也可以在某些指令中用作要由Dockerfile.该
${variable_name}语法还支持以下指定的一些标准 bash 修饰符:
${variable:-word}表示如果variable设置,则结果将是该值。如果variable未设置,word则将是结果。
${variable:+word}表示如果variable设置则为word结果,否则为空字符串。
使用 Bash 脚本和 Alpine/Centos
文件
FROM alpine #just change this to centos
ARG MYARG=""
ENV E_MYARG=$MYARG
ADD . /tmp
RUN chmod +x /tmp/script.sh && /tmp/script.sh
Run Code Online (Sandbox Code Playgroud)
脚本文件
#!/usr/bin/env sh
if [ -z "$E_MYARG" ]; then
echo "NO PARAM PASSED"
else
echo $E_MYARG
fi
Run Code Online (Sandbox Code Playgroud)
传递参数:
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
Run Code Online (Sandbox Code Playgroud)
没有 arg:
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
....
Run Code Online (Sandbox Code Playgroud)
小智 5
# The ARGs in front of FROM is for image
ARG IMLABEL=xxxx \
IMVERS=x.x
FROM ${IMLABEL}:${IMVERS}
# The ARGs after FROM is for parameters to be used in the script
ARG condition-x
RUN if [ "$condition-x" = "condition-1" ]; then \
echo "$condition-1"; \
elif [ "$condition-x" = "condition-1" ]; then \
echo "$condition-2"; \
else
echo "$condition-others"; \
fi
Run Code Online (Sandbox Code Playgroud)
build -t --build-arg IMLABEL --build-arg IMVERS --build-arg condition-x -f Dockerfile -t image:version .
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
94941 次 |
| 最近记录: |