如何使用 Docker 获取入口点脚本?
How to source an entry point script with Docker?
我有一张 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.
中评估脚本有关
有什么指导可以实现我想要的吗?看起来很明显,但我不知道。
在交互式 shell 中,source
告诉 shell 从文件中读取命令而不创建子 shell。在您的情况下,您希望初始 shell 从脚本执行命令。因此,您所要做的就是将脚本作为参数提供。请尝试以下操作:
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
但是,它是not a good idea到运行一个shell作为容器中的初始进程。这搞砸了信号处理。您会注意到您无法使用 Ctrl-C 停止执行。
因此,使用 CMD
而不是 ENTRYPOINT
来启动 shell。 id为1的初始进程应该是最小的init进程,比如.
当Docker启动容器时,有两部分,“入口点”和“命令”。当两者都指定时,“命令”部分作为 command-line 参数传递给“入口点”部分。
特别是,您显示的脚本具有非常典型的入口点脚本模式:
#!/bin/sh
# ... do some setup ...
# then run the CMD passed as command-line arguments
exec "$@"
如果您的 Docker 文件将此脚本命名为它的 ENTRYPOINT
那么您想将您想要的命令作为“命令”部分传递给 运行。如果你 运行 你的 shell 就像
docker run --rm -it gcr.io/docker:tag sh
然后 sh
将被传递到入口点脚本,它将进行设置,然后最终 运行 它。
(请记住,source
是一个 vendor-specific 扩展,在许多 shell 中并不存在,例如 Alpine 基础图像使用的最小 BusyBox shell,但是 .
表示相同的东西并且在 POSIX 标准中。由于容器只有 运行 一个进程,因此将一个进程作为“源”也没有任何意义这个文件”;它会设置一些环境变量,然后容器退出。入口点模式进行设置,然后 运行s 主容器命令。)
我有一张 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.
有什么指导可以实现我想要的吗?看起来很明显,但我不知道。
在交互式 shell 中,source
告诉 shell 从文件中读取命令而不创建子 shell。在您的情况下,您希望初始 shell 从脚本执行命令。因此,您所要做的就是将脚本作为参数提供。请尝试以下操作:
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
但是,它是not a good idea到运行一个shell作为容器中的初始进程。这搞砸了信号处理。您会注意到您无法使用 Ctrl-C 停止执行。
因此,使用 CMD
而不是 ENTRYPOINT
来启动 shell。 id为1的初始进程应该是最小的init进程,比如
当Docker启动容器时,有两部分,“入口点”和“命令”。当两者都指定时,“命令”部分作为 command-line 参数传递给“入口点”部分。
特别是,您显示的脚本具有非常典型的入口点脚本模式:
#!/bin/sh
# ... do some setup ...
# then run the CMD passed as command-line arguments
exec "$@"
如果您的 Docker 文件将此脚本命名为它的 ENTRYPOINT
那么您想将您想要的命令作为“命令”部分传递给 运行。如果你 运行 你的 shell 就像
docker run --rm -it gcr.io/docker:tag sh
然后 sh
将被传递到入口点脚本,它将进行设置,然后最终 运行 它。
(请记住,source
是一个 vendor-specific 扩展,在许多 shell 中并不存在,例如 Alpine 基础图像使用的最小 BusyBox shell,但是 .
表示相同的东西并且在 POSIX 标准中。由于容器只有 运行 一个进程,因此将一个进程作为“源”也没有任何意义这个文件”;它会设置一些环境变量,然后容器退出。入口点模式进行设置,然后 运行s 主容器命令。)