无法从入口点脚本正确获取环境文件

时间:2018-09-23 12:04:45

标签: shell docker docker-compose dockerfile docker-entrypoint

我正在尝试从条件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完成容器实例化。

在此先感谢您。

2 个答案:

答案 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