如何覆盖入口点并将 Bash 命令作为字符串传递?

red*_*888 12 bash docker dockerfile

我不想修改 Dockerfile。

我想覆盖入口点并运行任意命令,但这对我不起作用:

docker run -it --entrypoint /bin/bash myimage bash -c "echo aaaa &"
Run Code Online (Sandbox Code Playgroud)

我明白了/bin/bash: /bin/bash: cannot execute binary file

我希望能够在交互式进入容器之前立即启动后台作业,而无需修改 Dockerfile。

Dav*_*aze 16

当 Docker 启动容器时,它将“入口点”和“命令”部分组合成一个命令。该docker run --entrypoint选项只需要一个“单词”作为入口点命令。

所以,假设你需要运行some command --with an-arg。你需要

  1. 将其分解为文字
  2. docker run --entrypoint在图像名称之前传递第一个单词为,
  3. 将剩余的单词作为命令部分传递到图像名称之后。
# some command --with an-arg
docker run \
  --entrypoint some
  image-name \
  command --with an-arg

# ls -al /
docker run --rm \
  --entrypoint /bin/ls
  image-name \
  -al /

# bash -c "echo aaaa"
docker run --rm \
  --entrypoint /bin/bash \
  image-name \
  -c 'echo aaaa'
Run Code Online (Sandbox Code Playgroud)

这种结构有点尴尬。如果您控制图像,我倾向于建议使图像CMD成为一个完整的命令,并忽略它ENTRYPOINT或使其成为一个以完整命令作为参数的包装器(例如,以 结尾的 shell 脚本exec "$@")。

# Hard to replace with an alternate command:
# ENTRYPOINT python3 ./manage.py runserver

# Better:
CMD python3 ./manage.py runserver
Run Code Online (Sandbox Code Playgroud)
# Takes a complete command as arguments
# (MUST use JSON-array form)
ENTRYPOINT ["bundle", "exec"]

# Can be overridden at runtime
# (But whatever you supply will run in a Ruby Bundler context)
CMD ["rails", "server", "-b", "0.0.0.0"]
Run Code Online (Sandbox Code Playgroud)