如何使用 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:/#
到目前为止一切顺利,但我没有设法将其包含在 < 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当Docker启动一个容器时,有两个部分,“入口点”和“命令”。当两者都指定时,“命令”部分将作为命令行参数传递给“入口点”部分。
特别是,您显示的脚本具有非常典型的入口点脚本模式:
如果您的 Dockerfile 将此脚本命名为其
ENTRYPOINT
那么您希望将要运行的命令作为“命令”部分传递。如果您像这样运行 shell,那么
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:
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 justthen
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.)在交互式 shell 中,
source
告诉 shell 从文件中读取命令,而不创建子 shell。在您的情况下,您希望初始 shell 执行脚本中的命令。所以你所要做的就是将脚本作为参数。尝试以下操作:但是,它是 将 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: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 ofENTRYPOINT
to start the shell. The initial process with id 1 should be a minimal init process, such astini
.