执行带有args的命令并在docker运行时覆盖入口点

hi3rlvi2  于 2023-04-05  发布在  Docker
关注(0)|答案(3)|浏览(153)

我尝试使用接受参数的脚本执行来覆盖docker映像中的入口点,失败如下

▶ docker run --entrypoint "/bin/sh -c 'my-script.sh arg1 arg2'" my-image:latest
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/bin/sh -c 'myscript.sh arg1 arg2'": stat /bin/sh -c 'my-script.sh arg1 arg2': no such file or directory: unknown.

然而,当我执行到容器时,上面的命令成功了:

▶  docker run --entrypoint sh -it my-image:latest
~ $ /bin/sh -c 'my-script.sh arg1 arg2'
Success

我在语法中遗漏了什么吗?

fcwjkofz

fcwjkofz1#

请记住,容器镜像名称后面的参数只是传递给ENTRYPOINT脚本。因此,您可以编写:

docker run --entrypoint my-script.sh my-image:latest arg1 arg2

例如,如果我有my-script.sh(mode 0755),其中包含:

#!/bin/sh

for arg in "$@"; do
    echo "Arg: $arg"
done

Dockerfile是这样的:

FROM docker.io/alpine:latest

COPY my-script.sh /usr/local/bin/
ENTRYPOINT ["date"]

我可以跑:

docker run --rm --entrypoint my-script.sh my-image arg1 arg2

并得到输出:

Arg: arg1
Arg: arg2

如果你想运行任意序列的shell命令,你当然可以这样做:

docker run --rm --entrypoint sh my-image \
  -c 'ls -al && my-script.sh arg1 arg2'
tjvv9vkg

tjvv9vkg2#

如果你需要经常这样做,你可以重构你的Dockerfile,让它更容易做到。
Docker容器的主进程是通过连接“entrypoint”和“command”参数列表来运行的。在Dockerfile中,这些参数来自ENTRYPOINTCMD指令。在docker run命令中,这更棘手:在图像名称之后的任何内容都是“命令”部分,但是“入口点”部分需要由--entrypoint参数提供,它需要在图像名称之前,并且它只能是单个单词。
如果你需要定期替换命令,如果你在Dockerfile中使用CMD而不是ENTRYPOINT来设置它,语法会变得更清晰。

# Dockerfile
CMD ["some", "main", "command"] # not ENTRYPOINT

如果您进行了此更改,那么您可以将备用命令放在docker run命令中的图像名称之后,而无需--entrypoint选项,也无需将命令字符串拆分为图像名称。

docker run my-image:latest /bin/sh -c 'my-script.sh arg1 arg2'

我将推荐一种模式,其中ENTRYPOINT是一个 Package 器脚本,它进行一些首次设置,然后执行类似exec "$@"的操作来运行作为参数传递给它的命令。该设置与CMD优先方法兼容:入口点 Package 器将执行其设置,然后运行覆盖命令而不是图像的命令。

bttbmeg0

bttbmeg03#

不太好,但这对我来说很有效。docker run image“/bin/bash”“-c”“source ~/.bashrc && /bin/bash”

相关问题