如何使用Docker获取入口点脚本?

时间:2019-06-13 18:26:18

标签: bash docker conda entry-point

我有一个Docker映像,我可以运行它:

docker run -it --entrypoint="/bin/bash" gcr.io/docker:tag

然后我可以通过以下方式获取脚本:

root@86bfac2f6ccc:/# source entrypoint.sh

脚本如下:

more entrypoint.sh
#!/bin/bash
. /env.sh
. /root/miniconda3/etc/profile.d/conda.sh
conda activate base
exec "$@"

激活基本导航:

(base) root@86bfac2f6ccc:/#

到目前为止还不错,但是我没有设法将其包含在Dockerfile中或作为docker run的参数:

我尝试了很多事情:

例如:

docker run -it --entrypoint="/bin/bash"  gcr.io/docker:tag  source entrypoint.sh
/bin/bash: source: No such file or directory

但是该脚本存在并且可以执行:

docker run -it --entrypoint="/bin/ls"  gcr.io/docker:tag -la
...
-rwxr-xr-x  1 root root   94 Apr 26 20:36 entrypoint.sh
...

或者:

docker run -it --entrypoint="/bin/bash"  gcr.io/docker:tag  ". /entrypoint.sh"
/bin/bash: . /entrypoint.sh: No such file or directory

或在Docker文件中:

ENTRYPOINT ["source", "/entrypoint.sh"]

我想我遇到的问题可能与source在当前shell中评估脚本这一事实有关。

实现我想要的任何指导?似乎很明显,但我不明白。

2 个答案:

答案 0 :(得分:1)

当Docker启动一个容器时,有两个部分,“入口点”和“命令”。如果同时指定了两者,则“命令”部分将作为命令行参数传递到“入口点”部分。

特别是,您显示的脚本具有一个非常典型的入口点脚本模式:

#!/bin/sh
# ... do some setup ...
# then run the CMD passed as command-line arguments
exec "$@"

如果您的Dockerfile将此脚本命名为其ENTRYPOINT,则您希望将要运行的命令作为“命令”部分传递。如果您只运行shell

docker run --rm -it gcr.io/docker:tag sh

然后将sh传递到入口点脚本,该脚本将进行设置,然后最终运行它。

(请记住,source是特定于供应商的扩展,并不存在于许多shell中,例如Alpine基本映像使用的最小BusyBox shell,但是.的含义相同,并且在POSIX标准中,由于容器仅运行一个进程,因此将一个进程“作为该文件的源”也没有任何意义;它会设置一些环境变量,然后这样做,容器退出了。入口点模式进行设置,然后运行主容器命令。)

答案 1 :(得分:0)

在交互式外壳程序中,source告诉外壳程序从文件读取命令而不创建子外壳程序。在您的情况下,您希望初始外壳程序从脚本执行命令。因此,您要做的就是将脚本作为参数。请尝试以下操作:

ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]

不过,not a good idea是在容器中运行外壳程序作为初始过程。这搞砸了信号处理。您会注意到无法使用Ctrl-C停止执行。 因此,使用CMD而不是ENTRYPOINT启动外壳程序。 ID为1的初始进程应为最小初始化进程,例如tini