我正在尝试从条件entrypoint.sh脚本中获取一个.env文件,该脚本的一部分如下所示:
if [ -f "some-env-file.env" ]; then
source some-env-file.env
在上述源命令之后,在.env文件中找到的环境变量的简单回显,将输出正确的值,然后成功执行了入口点脚本中提供的操作。
但是,当我在实例化容器中执行docker exec -it
时,env文件看起来好像不是源文件。只有当我再次从那里采购时,我才能获得理想的结果。 (更具体地说,env文件用于指向python的特定运行时环境。因此,在进入容器后,只有当我再次获取env文件时,才能正确调用python。)
我在做什么错了?
作为参考,以下是我的Dockerfile的最后几行(没什么特别的):
COPY ./entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
使用docker-compose
yaml完成容器实例化。
在此先感谢您。
答案 0 :(得分:2)
Docker启动流程是Docker设置一些环境变量(来自Dockerfile和docker run -e
选项),然后启动容器的入口点。入口点内发生的任何事情都不在Docker的权限范围之内。特别是,通过docker exec
启动的调试外壳程序不是入口点的子级,并且不会继承在那里设置的环境变量。 (注意:我在任何地方的Docker文档中都找不到明确声明的内容。)
要尝试的一个不错的实验是运行:
% docker run -d --name test busybox sh -c 'sleep 60; sleep 60'
6c6aada7e5299e816e9d12dfab9845cc396485a46d909255375128b87ee5eedf
% docker exec test ps -o pid,ppid,comm
PID PPID COMMAND
1 0 sh
6 1 sleep
7 0 ps
容器的根进程是一个外壳程序,该外壳程序获得进程ID 1,并启动一个sleep
子进程,该子进程具有进程ID 6和父进程ID1。docker exec
ps
命令获取新的进程ID,但人工父进程ID为0 –它不是容器根进程的子进程。
如果要调试映像的启动环境,请使用典型的入口点脚本,例如
#!/bin/sh
. /env.sh
exec "$@"
您可以docker run --rm -it myimage sh
,生成的shell将通过您的入口点脚本启动。但是正如您观察到的那样,尝试通过docker exec
进行调试不会进入入口点序列的任何部分。
答案 1 :(得分:0)
将此添加到我的entrypoint.sh
中解决了该问题:
cat >> /etc/bash.bashrc <<EOF
if [ -f some-env-file.env ]; then
source some-env-file.env
fi
EOF