Env 文件未正确来源于入口点脚本

Env file not properly sourced from entrypoint script

我正在尝试从条件 entrypoint.sh 脚本中获取 .env 文件,其中的一部分如下所示:

if [ -f "some-env-file.env" ]; then
source some-env-file.env

在 .env 文件中发现的环境变量的简单回显,就在上面的 source 命令之后,输出正确的值,并且在入口点脚本中提供的操作成功执行。

但是,当我在实例化的容器中执行 docker exec -it 时,env 文件看起来好像不是来源。只有当我从那里再次采购时,我才能得到理想的结果。 (更具体地说,env文件是用来指向python的特定运行环境的。所以进入容器后,只有在我再次source env文件时才能正确调用python)。

我做错了什么?

作为参考,这些是我的 Dockerfile 的最后几行(没什么特别的):

COPY ./entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]

容器实例化是使用 docker-compose yaml 完成的。

提前致谢,如果之前有人问过这个问题,我们深表歉意。

Docker启动流程是Docker设置一些环境变量(来自Docker文件和docker run -e选项)然后启动容器的入口点。入口点内发生的任何事情都在 Docker 的权限之外。特别是,通过 docker exec 启动的调试 shell 不是入口点的子项,不会继承在那里设置的环境变量。 (注意:我无法在任何地方的 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

容器的根进程是一个 shell,它获得进程 ID 1,并启动一个 sleep 子进程,进程 ID 为 6,父进程 ID 为 1。docker exec ps 命令获得了一个新的进程 ID,但其人工父进程 ID 为 0 – 它不是容器根进程的子进程。

如果您想调试映像的启动环境,可以使用像

这样的典型入口点脚本
#!/bin/sh
. /env.sh
exec "$@"

您可以 docker run --rm -it myimage sh 并且生成的 shell 将通过您的入口点脚本启动。但是正如您所观察到的,尝试通过 docker exec 调试它不会通过入口点序列的任何部分。

将此添加到我的 entrypoint.sh 解决了问题:

cat >> /etc/bash.bashrc <<EOF
if [ -f some-env-file.env ]; then
  source some-env-file.env
fi
EOF