Execute a script before CMD
搬运工:AS发送文档有一个CMD指令只能在一dockerfile。如果你只有一个列表比颞下颌关节会带负载效应。
我想执行一个简单的bash脚本(这过程码头环境变量在命令(CMD)是初始化的案例)。
有没有任何方式这样做?
使用自定义入口点
创建一个自定义的入口点,它可以满足您的需要,然后在末尾执行命令。
NOTE: if your image already defines a custom entrypoint, you may need to extend it rather than replace it, or you may change behavior you need.
入口:
1 2 3 4 5 6 | #!/bin/sh ## Do whatever you need with env vars here ... # Hand off to the CMD exec"$@" |
Dockerfile:
1 2 3 4 | COPY entrypoint.sh /entrypoint.sh RUN chmod 755 /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] |
Docker将运行您的入口点,使用cmd作为参数。如果您的命令是
1 | /entrypoint.sh init |
entrypoint脚本末尾的
entrypoint和cmd的使用经常使Docker的新手感到困惑。在评论中,你对此表示困惑。这是它的工作原理和原因。
入口点是容器中运行的初始内容。它将cmd作为参数列表。因此,在本例中,在容器中运行的是以下参数列表:
1 2 3 4 5 6 | # ENTRYPOINT = /entrypoint.sh # CMD = init ["/entrypoint.sh","init"] # or shown in a simpler form: /entrypoint.sh init |
不要求图像具有入口点。如果您没有定义一个,Docker有一个默认值:
因此,在您最初的情况下,没有入口点,并且使用
1 2 3 4 | /bin/sh -c 'init' ^--------^ ^--^ | \------- CMD \--------------- ENTRYPOINT |
起初,docker只提供了cmd,
在我上面展示的示例中,入口点被一个自定义脚本替换。(虽然它最终仍由
该入口点将cmd作为is参数。在entrypoint.sh脚本的末尾是
1 | exec"init" |
因此,当脚本完成时,它就消失了,并被
在注释中,您询问了如何在dockerfile中添加cmd。是的,你能做到。
Dockerfile:
1 | CMD ["init"] |
或者,如果您有更多的命令,例如,像
1 | CMD ["init","-a","-b"] |
丹的回答是正确的,但我发现执行起来相当混乱。对于相同情况下的那些,这里有一些代码示例,说明我是如何实现他对使用entrypoint而不是cmd的解释的。
下面是我的dockerfile中的最后几行:
1 2 3 | #change directory where the mergeandlaunch script is located. WORKDIR /home/connextcms ENTRYPOINT ["./mergeandlaunch","node","keystone.js"] |
下面是mergeandlaunch bash shell脚本的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!/bin/bash #This script should be edited to execute any merge scripts needed to #merge plugins and theme files before starting ConnextCMS/KeystoneJS. echo Running mergeandlaunch script #Execute merge scripts. Put in path to each merge script you want to run here. cd ~/theme/rtb4/ ./merge-plugin #Launch KeystoneJS and ConnextCMS cd ~/myCMS exec"$@" |
以下是代码的执行方式:
感谢丹的回答。
虽然我发现我必须在dockerfile里做这样的事情:
1 2 3 4 | WORKDIR / COPY startup.sh / RUN chmod 755 /startup.sh ENTRYPOINT sh /startup.sh /usr/sbin/init |
注意:我将脚本startup.sh命名为entrypoint.sh,而不是entrypoint.sh。
这里的关键是我需要提供"sh",否则我会不断得到"no such file…"错误从"docker logs-f container_name"中出现。
见:https://github.com/docker/compose/issues/3876