我有一个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
评估当前外壳中的脚本有关。
有什么指导来实现我想要的吗?这似乎很明显,但我不知道。
docker启动容器时,分为两个部分:入口点和命令。当两者都指定时,"命令"部分将作为命令行参数传递给"入口点"部分。
具体来说,您显示的脚本具有非常典型的入口点脚本模式:
#!/bin/sh
# ... do some setup ...
# then run the CMD passed as command-line arguments
exec "$@"
如果您的Dockerfile将此脚本命名为ENTRYPOINT
,则您希望传递要作为"命令"部分运行的命令。如果您仅以身份运行您的外壳
docker run --rm -it gcr.io/docker:tag sh
然后sh
将被传递给入口点脚本,该脚本将执行设置并最终运行它。
(请记住,source
是特定于供应商的扩展,并不存在于许多外壳中,例如阿尔卑斯基本镜像使用的最小BusyBox外壳,但.
的含义是相同的,并且在POSIX标准中。因为一个容器只运行一个进程,所以将该进程作为"源文件"也没有实际意义;它会设置一些环境变量,然后它会这样做,这样容器就会退出。入口点模式执行设置,然后运行主容器命令。)