如何将参数从文件传递给dockerfile

时间:2019-07-18 09:32:34

标签: docker dockerfile

我正在尝试将参数从文件传递到docker文件。

我试图将文件复制到docker容器中并使用source命令。

Dockerfile

COPY docker.env .
RUN /bin/bash -c "source docker.env"

Docker.env

BuildMode="release"

也没有用的另一尝试

export BuildMode="release"

没有错误,但是当我尝试打印ECHO $BuildMode时,它没有在其中打印值,就好像它没有在其中获取值。

但是,如果我创建了一个docker容器并在docker容器中尝试相同的代码,则它可以正常工作。

4 个答案:

答案 0 :(得分:1)

我对空白和旧的macOS bash version 3有问题。由于我必须为所有人使用macOS进行工作,因此我必须做出解决方法并提出此解决方案

while IFS= read -r line; do
  echo $line
  opts+=(--build-arg "$line")
done < ".ENV.FILE"

docker build "${opts[@]}" -t ${IMAGE_NAME}:${DTAG} -t ${IMAGE_NAME}:${K8S_NS} .

.ENV.FILE如下所示:

APP_PORT=3030
APP_HOST=0.0.0.0
APP_API_URL=FOO
APP_API_WHITE=S P A C E

我希望它对某人有帮助

答案 1 :(得分:0)

然后您可以使用--build-arg,它将在构建时将--build-arg key=value的参数传递给dockerfile,请参考this

您只需要使用sed从您的环境文件中获取并在构建dockerfile时将它们组合为--build-arg key=value格式,如下所示:

文档文件:

FROM ubuntu:16.04

ARG BuildMode
ENV BuildMode=${BuildMode}

RUN echo $BuildMode

docker.env:

BuildMode="release"

命令:

docker build -t abc:1 $(cat docker.env | sed 's@^@--build-arg @g' | paste -s -d " ") . --no-cache

输出:

shubuntu1@shubuntu1:~/1$ docker build -t abc:1 $(cat docker.env | sed 's@^@--build-arg @g' | paste -s -d " ") . --no-cache
Sending build context to Docker daemon  3.072kB
Step 1/4 : FROM ubuntu:16.04
 ---> 13c9f1285025
Step 2/4 : ARG BuildMode
 ---> Running in 3bc49fbb0af4
Removing intermediate container 3bc49fbb0af4
Step 3/4 : ENV BuildMode=${BuildMode}
 ---> Running in 4c253fba0b36
Removing intermediate container 4c253fba0b36
 ---> c70f7f535d1f
Step 4/4 : RUN echo $BuildMode
 ---> Running in 5fef72f28975
"release"
Removing intermediate container 5fef72f28975
 ---> 4b5555223b5b
Successfully built 4b5555223b5b
Successfully tagged abc:1

答案 2 :(得分:0)

最终,我找到了问题,问题是docker在构建时正在移除中间容器,因此未存储该变量,如果docker build是使用-rm标志运行的。 所以我的补救措施是执行先前代码本身中的代码

RUN /bin/bash -c 'source docker.env; echo $Environment'

如果代码很大,我知道这不是一个好主意,但这是使用-rm和bash代码的唯一方法
-------------------------------------------------- - - (要么) - - - - - - - - - - - - - - - - - - - - - - ---------------------

设置--rm = false标志并尝试,但是我没有尝试过,因为我必须使用-rm标志运行,因为它是可视代码中的默认代码,我不应该更改它

答案 3 :(得分:0)

每个Dockerfile RUN命令都会在新的shell中启动一个新的容器。您在此处运行的export命令不会在以后的层中起作用。如果您使用.或bash的source之类的非标准供应商扩展来读取设置变量的脚本,那么在以后的层中将永远没有任何作用。

FROM busybox
RUN export FOO=foo
CMD echo FOO is $FOO # doesn't actually print a value

如果要设置环境变量,则需要使用Dockerfile ENV指令。

FROM busybox
ENV FOO=foo
CMD echo FOO is $FOO
# Compare: docker run -e FOO=bar myimage

如果绝对必须在文件中,则必须在每个RUN命令中读取该命令,具体取决于那里设置的变量。您还需要安排在容器启动时将其读取。通常的方法是编写一个ENTRYPOINT来读取环境文件,然后运行任何映像的CMD

#!/bin/sh
# I am entrypoint.sh

# Read in the environment file
. /env.sh

# Run the CMD, as the main container process
exec "$@"
# I am Dockerfile
FROM busybox
COPY env.sh entrypoint.sh /
RUN chmod +x /entrypoint.sh

# Example: Do something that depends on the variable value
RUN . /env.sh && echo FOO is $FOO
# Need to repeat "." in every RUN line
RUN . /env.sh && echo BAR is $BAR

# Startup-time instructions
ENTRYPOINT ["/env.sh"]  # must use JSON syntax
CMD echo FOO is $FOO
# Compare: docker run -v $PWD/env.sh:/env.sh myimage

(出于相同的原因,您需要在外壳WORKDIR上使用Docker cd来持久地切换目录;并且您不应该使用环境管理器Python虚拟环境,Node的nvm,或Ruby在Docker中的rvm,因为管理环境变量很烦人,并且Docker已经提供了隔离的执行环境。)