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

发布于 2025-01-11 19:40:00 字数 1240 浏览 0 评论 0原文

我有一个 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:/#

到目前为止一切顺利,但我没有设法将其包含在 < code>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 评估 a 的事实有关当前 shell 中的脚本。

有什么指导可以实现我想要的吗?这看起来很明显,但我不知道。

I have an Docker image and I can run it:

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

Then I can source a script in the following way:

root@86bfac2f6ccc:/# source entrypoint.sh

The script looks like that:

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

Which activate the base env:

(base) root@86bfac2f6ccc:/#

So far so good but I don't managed to include this in the Dockerfile or as parameters to docker run:

I tried many things:

For example:

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

But the script exist and can be executed:

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

Or:

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

Or in the Docker file:

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

I guess the issue I have is maybe related the fact that source evaluate a script in the current shell.

Any guidance to achieve what I want ? It seems quite obvious but I am out of idea.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

够运 2025-01-18 19:40:00

当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,但 . 的含义相同由于容器仅运行一个进程,因此该进程“获取此文件”也没有任何意义;它会设置一些环境变量,然后容器就完成了。入口点模式执行设置。然后运行主容器命令。)

When Docker launches a container, there are two parts, the “entrypoint” and the “command”. When both are specified, the “command” part is passed as command-line arguments to the “entrypoint” part.

In particular, the script you show has a very typical pattern for an entrypoint script:

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

If your Dockerfile names this script as its ENTRYPOINT then you want to pass the command you want to run as the “command” part. If you run your shell as just

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

then sh will be passed to the entrypoint script, which will do the setup and then eventually run it.

(Remember that source is a vendor-specific extension and doesn’t exist in many shells, like the minimal BusyBox shell that Alpine base images use, but that . means the same thing and is in the POSIX standard. Since a container only runs one process it also doesn’t really make sense for that one process to be “source this file”; it would set up some environment variables, and then it’s done so the container exits. The entrypoint pattern does the setup and then runs the main container command.)

把回忆走一遍 2025-01-18 19:40:00

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

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

但是,它是 将 shell 作为容器中的初始进程运行并不是一个好主意。这会搞砸信号处理。您会注意到您无法使用 Ctrl-C 停止执行。
因此,请使用 CMD 而不是 ENTRYPOINT 来启动 shell。 id 为 1 的初始进程应该是最小的 init 进程,例如 tini

In an interactive shell, source tells the shell to read the commands from the file without creating a subshell. In your case, you want the initial shell to execute the commands from a script. So all you have to do is give the script as an argument. Try the following:

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

However, it is not a good idea to run a shell as the initial process in a container. That screws up the signal handling. You'll notice that you cannot stop execution with Ctrl-C.
Therefore, use CMD instead of ENTRYPOINT to start the shell. The initial process with id 1 should be a minimal init process, such as tini.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文