shell - 未从入口点脚本正确获取 Env 文件

标签 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。

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

最佳答案

Docker 启动流程是 Docker 设置一些环境变量(来自 Dockerfile 和 docker run -e 选项),然后启动容器的入口点。入口点内发生的任何事情都超出了 Docker 的权限范围。特别是通过 docker exec 启动的调试 shell。不是入口点的 child ,不会继承在那里设置的环境变量。 (注意:我无法在任何地方的 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 command 获取一个新的进程 ID,但人工父进程 ID 为 0——它不是容器根进程的子进程。

如果您想调试图像的启动环境,使用典型的入口点脚本,例如
#!/bin/sh
. /env.sh
exec "$@"

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

关于shell - 未从入口点脚本正确获取 Env 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52465931/

相关文章:

docker - rcedit.exe失败,退出代码为193。wine : Bad EXE format

linux - 如何在多个符号链接(symbolic link)中查找文件

python - 重定向 subprocess.call 输出不起作用

docker - 链接运行在不同主机上的Docker容器?

jboss - 未在dockerfile中添加Wildfly独立文件

wordpress - Docker Compose WordPress 卷显示为空

linux - 如何确保用户输入有效的 switch case 选项?

linux - 为什么脚本无法识别文件扩展名?

docker - 无法在 Docker 中更新 Debian 容器

docker - Docker构建:mkdir创建文件夹,但它们在运行时消失