我正在创建一个类似以下docker项目的类似问题的图像:
FROM alpine:3.9.3
COPY ./env.sh /env.sh
RUN source /env.sh
CMD env
TEST=test123
我建立了图像
docker build -t sandbox .
并运行它
docker run --rm sandbox
输出是
HOSTNAME=72405c43801b
SHLVL=1
HOME=/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
我的环境变量丢失了。
在实际项目中,我必须为IBM DB2客户端安装更长的复杂脚本,该脚本也设置环境变量。如何在不读取整个安装过程并使用dockerfile中的ENV
设置所有变量的情况下实现它?
编辑:在实际项目中,文件env.sh
是作为安装过程的一部分创建的,并且不能从容器外部获得。根据执行的系统设置环境变量。如果我在主机上运行它,它将在guest虚拟机中设置错误的变量。
部分真实剧本是
if [ -f ${INST_DIR?}/tools/clpplus.jar ]; then
AddRemoveString CLASSPATH ${INST_DIR?}/tools/clpplus.jar a
fi
if [ -f ${INST_DIR?}/tools/antlr-3.2.jar ]; then
AddRemoveString CLASSPATH ${INST_DIR?}/tools/antlr-3.2.jar a
fi
if [ -f ${INST_DIR?}/tools/jline-0.9.93.jar ]; then
AddRemoveString CLASSPATH ${INST_DIR?}/tools/jline-0.9.93.jar a
fi
if [ -f ${INST_DIR?}/java/db2jcc.jar ]; then
AddRemoveString CLASSPATH ${INST_DIR?}/java/db2jcc.jar a
fi
if [ -f ${INST_DIR?}/java/db2jcc_license_cisuz.jar ]; then
AddRemoveString CLASSPATH ${INST_DIR?}/java/db2jcc_license_cisuz.jar a
fi
它会检查安装并根据此设置变量。由于在主机上没有DB2安装,因此不会设置变量。
每个Dockerfile RUN
步骤都运行一个新容器和一个新shell。如果您尝试在一个shell中设置环境变量,稍后将无法看到它。例如,您可以尝试使用此Dockerfile:
FROM busybox
ENV FOO=foo1
RUN export FOO=foo2
RUN export BAR=bar
CMD echo FOO is $FOO, BAR is $BAR
# Prints "FOO is foo1, BAR is "
这有三个很好的解决方案。从最简单/最好到最难/最复杂的顺序:
/usr
这样的“系统”位置;无论如何它都会在Docker镜像中被隔离。 (不要使用像Python虚拟环境那样的额外隔离工具,或者像nvm
或rvm
这样的版本管理器;只需安装你需要的特定东西。)ENV
。这将有效:
FROM busybox
ENV FOO=foo2
ENV BAR=bar
CMD echo FOO is $FOO, BAR is $BAR
# Prints "FOO is foo2, BAR is bar"
#!/bin/sh
# Read in the file of environment settings
. /opt/wherever/env
# Then run the CMD
exec "$@"
COPY
这个脚本进入你的Dockerfile。让它成为ENTRYPOINT
;让CMD
成为你实际运行的东西。
FROM busybox
WORKDIR /app
COPY entrypoint.sh .
COPY more_stuff .
ENTRYPOINT ["/app/entrypoint.sh"]
CMD ["/app/more_stuff/my_app"]
如果您关心这些事情,那么您在docker inspect
或docker exec
调试shell中将无法看到通过此方法设置的环境变量;但如果你docker run -it ... sh
他们将是可见的。这是一个非常有用且重要的模式,我几乎总是在我的Dockerfiles中使用CMD
,除非我特意尝试像这样进行首次设置。我最终在bash脚本中执行了dockerfile的多步构建。
步骤1.设置Dockerfile以包含所有需要为环境变量提供文件的位置。
第2步。在docker文件源中环境变量并将环境回显到文件。
运行源$(pwd)/buildstepenv_rhel72_64.sh && source / opt / rh / devtoolset-8 / enable && env | sort -u> /tmp.env“
第3步使用标记构建图像。
docker build -t $ {image} _dev。
步骤4使用标记运行图像以获取环境变量并将它们添加到docker文件的末尾
docker run --rm $ {image} _dev cat /tmp.env | sed的/ $ /“/; s / = / =”/; s / ^ / ENV /'>> logs / docker / Dockerfile。$ {step}
第5步构造dockerfile的其余部分
这应该够了吧:
RUN export $(cat env.sh | xargs)
希望能帮助到你!