我正在尝试将参数从文件传递到docker文件。
我试图将文件复制到docker容器中并使用source命令。
COPY docker.env .
RUN /bin/bash -c "source docker.env"
BuildMode="release"
export BuildMode="release"
没有错误,但是当我尝试打印ECHO $BuildMode
时,它没有在其中打印值,就好像它没有在其中获取值。
但是,如果我创建了一个docker容器并在docker容器中尝试相同的代码,则它可以正常工作。
答案 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已经提供了隔离的执行环境。)