1

我正在尝试从条件 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-composeyaml 完成的。

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

4

2 回答 2

2

Docker 启动流程是 Docker 设置一些环境变量(来自 Dockerfile 和docker run -e选项),然后启动容器的入口点。入口点内发生的任何事情都超出了 Docker 的权限范围。特别是,通过启动的调试 shelldocker 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

容器的根进程是一个 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不会通过入口点序列的任何部分。

于 2018-09-23T17:25:52.677 回答
0

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

cat >> /etc/bash.bashrc <<EOF
if [ -f some-env-file.env ]; then
  source some-env-file.env
fi
EOF
于 2018-09-25T11:27:29.017 回答