英文:
build singularity recipe with docker ENTRYPOINT/CMD equivalent functionality
问题
I have a dockerfile which ends
ENTRYPOINT ["sh"]
CMD ["runscript.sh"]
我有一个 Dockerfile,其中包含以下内容:
ENTRYPOINT ["sh"]
CMD ["runscript.sh"]
I can run docker with an argument (a shell script) that overrides "runscript.sh" (if i wish). Note: the shell scripts are provided by a --bind
mount
如果需要,我可以运行 Docker 并使用一个参数(一个 shell 脚本)来覆盖 "runscript.sh"。请注意:这些 shell 脚本是通过 --bind
挂载提供的。
I am translating my Dockerfile to a Singularity recipe. From my understanding i can replicate this ENTRYPOINT/CMD functionality using the "%startscript" label. I am trying:
我正在将我的 Dockerfile 翻译成 Singularity 配方。根据我的理解,我可以使用 "%startscript" 标签来复制 ENTRYPOINT/CMD 的功能。我尝试了以下方法:
%startscript
exec "$@"
then run an instance of the container using
然后,使用以下命令运行容器的一个实例:
singularity instance start --bind /hostpath:/containerpath model.sif instancename script.sh
When i do this i get the message:
但是当我这样做时,我收到以下消息:
/.singularity.d/startscript: 4: exec: script.sh: not found
I know i am doing this all wrong, but cant seem to work out what.
我知道我做错了什么,但似乎无法找出问题所在。
Note: if i replace exec "$@"
with ./script.sh
then the script is executed but i am limited to having a script with this name. I want the flexibility to pass any named script.
注意:如果我将 exec "$@"
替换为 ./script.sh
,则脚本将被执行,但我只能使用这个名称的脚本。我希望具有灵活性以传递任何命名的脚本。
英文:
I have a dockerfile which ends
ENTRYPOINT ["sh"]
CMD ["runscript.sh"]
I can run docker with an argument (a shell script) that overrides "runscript.sh" (if i wish). Note: the shell scripts are provided by a --bind
mount
I am translating my Dockerfile to a Singularity recipe. From my understanding i can replicate this ENTRYPOINT/CMD functionality using the "%startscript" label. I am trying:
%startscript
exec "$@"
then run an instance of the container using
singularity instance start --bind /hostpath:/containerpath model.sif instancename script.sh
When i do this i get the message:
/.singularity.d/startscript: 4: exec: script.sh: not found
I know i am doing this all wrong, but cant seem to work out what.
Note: if i replace exec "$@"
with ./script.sh
then the script is executed but i am limited to having a script with this name. I want the flexibility to pass any named script.
答案1
得分: 0
在您的原始 Dockerfile 中:
- 删除
ENTRYPOINT
- 确保
CMD
包括某种路径,如CMD ["./runscript.sh"]
- 确保脚本的第一行是 "shebang" 行,
#!/bin/sh
- 在主机系统上确保脚本是可执行的,
chmod +x runscript.sh
,并检查是否将更改提交到源代码控制
这是您需要在主机系统上运行 ./runscript.sh
而无需使用 Docker 的相同步骤,相同的规则适用。
在您展示的脚本中,您只是运行 exec "$@"
,可能作为传递 CMD
作为参数的入口脚本。您的原始 Dockerfile 使用 sh
(ENTRYPOINT
值)在给定的 CMD
之前添加了一个 CMD
,但这个包装器没有这样做,这就是为什么会出现不同行为的原因。
总的来说,我不鼓励将语言解释器的名称拆分到 ENTRYPOINT
中。我更喜欢 CMD
是一个完整的命令的模式,与您展示的入口包装脚本兼容。还有一种模式是 ENTRYPOINT
是一个完整的命令,CMD
是其参数(Kubernetes 将这些选项称为 command:
和 args:
)。您这里所做的有点像是一半的方式:如果您覆盖 CMD
,那么您必须重复程序名称,但实际上只能运行实现为 shell 脚本的程序。
英文:
In your original Dockerfile:
- Remove the
ENTRYPOINT
- Make sure the
CMD
includes some sort of path, likeCMD ["./runscript.sh"]
- Make sure the first line of the script is a "shebang" line,
#!/bin/sh
- On the host system, make sure the script is executable,
chmod +x runscript.sh
, and check that change into source control
This is the same set of steps you'd need to do to be able to run ./runscript.sh
on the host system, without Docker, and the same rules apply.
In the script you show, you're just running exec "$@"
, presumably as an entrypoint script being passed the CMD
as arguments. Your original Dockerfile prepended whatever CMD
it was given with sh
(the ENTRYPOINT
value), but this wrapper doesn't, and that's why you're getting different behavior.
In general I wouldn't encourage splitting out the name of a language interpreter into ENTRYPOINT
. I prefer a pattern of CMD
being a complete command, which is compatible with the sort of entrypoint wrapper script you show. There's also a pattern of ENTRYPOINT
being a complete command and CMD
its arguments (Kubernetes calls these options command:
and args:
). What you have here is kind of a half way, though: if you override CMD
then you must repeat the program name, but you can only actually run programs that are implemented as shell scripts.
答案2
得分: 0
你需要使用 %runscript
而不是 %startscript
,然后你可以传递一个参数给 run
命令,该参数将替代配方中的默认值,例如,在配方文件中:
%runscript
./runscript.sh
然后,根据你想要运行默认容器脚本或 "newscript",使用以下之一:
要运行默认容器脚本:
singularity exec image.sif
要运行 "newscript":
singularity exec image.sif newscript.sh
英文:
You need to use
%runscript
and not
%startscript
Then you can pass an argument to run command which will be used in place of the default value in the recipe,
singularity exec image argument
eg. in the recipe file
%runscript
./runscript.sh
then use either
singularity exec image.sif
or
singularity exec image.sif newscript.sh
depending on whether you want to run the default container script or the "newscript"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论