Dr.*_*ade 3 bash entry-point docker conda
我有一个 Docker 镜像,我可以运行它:
docker run -it --entrypoint="/bin/bash" gcr.io/docker:tag
Run Code Online (Sandbox Code Playgroud)
然后我可以通过以下方式获取脚本:
root@86bfac2f6ccc:/# source entrypoint.sh
Run Code Online (Sandbox Code Playgroud)
该脚本如下所示:
more entrypoint.sh
#!/bin/bash
. /env.sh
. /root/miniconda3/etc/profile.d/conda.sh
conda activate base
exec "$@"
Run Code Online (Sandbox Code Playgroud)
激活基础环境:
(base) root@86bfac2f6ccc:/#
Run Code Online (Sandbox Code Playgroud)
到目前为止一切顺利,但我没有设法将其包含在Dockerfile或 作为参数中docker run:
我尝试了很多东西:
例如:
docker run -it --entrypoint="/bin/bash" gcr.io/docker:tag source entrypoint.sh
/bin/bash: source: No such file or directory
Run Code Online (Sandbox Code Playgroud)
但是脚本存在并且可以执行:
docker run -it --entrypoint="/bin/ls" gcr.io/docker:tag -la
...
-rwxr-xr-x 1 root root 94 Apr 26 20:36 entrypoint.sh
...
Run Code Online (Sandbox Code Playgroud)
或者:
docker run -it --entrypoint="/bin/bash" gcr.io/docker:tag ". /entrypoint.sh"
/bin/bash: . /entrypoint.sh: No such file or directory
Run Code Online (Sandbox Code Playgroud)
或者在 Docker 文件中:
ENTRYPOINT ["source", "/entrypoint.sh"]
Run Code Online (Sandbox Code Playgroud)
我想我遇到的问题可能与source在当前 shell中评估脚本有关。
任何指导来实现我想要的?这似乎很明显,但我不知道。
在交互式 shell 中,source告诉 shell 从文件中读取命令而不创建子 shell。在您的情况下,您希望初始 shell 执行脚本中的命令。所以你所要做的就是将脚本作为参数。请尝试以下操作:
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
Run Code Online (Sandbox Code Playgroud)
但是,将 shell 作为容器中的初始进程运行并不是一个好主意。这会搞砸信号处理。您会注意到您无法使用 Ctrl-C 停止执行。因此,使用CMD而不是ENTRYPOINT启动shell。id 为 1 的初始进程应该是最小的 init 进程,例如tini。
当 Docker 启动一个容器时,有两个部分,“入口点”和“命令”。当两者都被指定时,“命令”部分作为命令行参数传递给“入口点”部分。
特别是,您显示的脚本具有非常典型的入口点脚本模式:
#!/bin/sh
# ... do some setup ...
# then run the CMD passed as command-line arguments
exec "$@"
Run Code Online (Sandbox Code Playgroud)
如果您的 Dockerfile 将此脚本命名为它,ENTRYPOINT那么您希望将要运行的命令作为“命令”部分传递。如果你运行你的shell
docker run --rm -it gcr.io/docker:tag sh
Run Code Online (Sandbox Code Playgroud)
thensh将被传递到入口点脚本,该脚本将进行设置并最终运行它。
(请记住,这source是一个特定于供应商的扩展,并且不存在于许多 shell 中,例如 Alpine 基础映像使用的最小 BusyBox shell,但这.意味着相同的事情并且在 POSIX 标准中。由于容器只运行一个进程,因此那个进程作为“源文件”也没有任何意义;它会设置一些环境变量,然后完成容器退出。入口点模式进行设置,然后运行主容器命令。 )