bash 成功等待脚本后如何启动docker容器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39860969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 15:15:24  来源:igfitidea点击:

How to start docker container after succesfull wait-for-it script

mysqlnode.jsbashdocker

提问by DenCowboy

I'm using a wait-for-it script to check if the database is up before I'm launching my other app.

在启动其他应用程序之前,我正在使用等待脚本来检查数据库是否已启动。

#!/bin/bash

set -e

host=""
shift
cmd="$@"

until psql -h "$host" -U "postgres" -c '\l'; do
  >&2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

>&2 echo "Postgres is up - executing command"
exec $cmd

I found this script here. Now my app-container stops running with MySQL is up - executing command. So the script was successful (db is running) but it's not clear for me how to execute the real CMD (after the script) which is in my dockerfile of my app.

我在这里找到了这个脚本。现在我的应用程序容器停止运行MySQL is up - executing command。所以脚本是成功的(db 正在运行),但我不清楚如何执行我的应用程序的 dockerfile 中的真正 CMD(在脚本之后)。

This is the end of my dockerfile:

这是我的 dockerfile 的结尾:

COPY docker-entrypoint.sh /entrypoint.sh
COPY ./wait-for-it.sh wait-for-it.sh
ENTRYPOINT ["/entrypoint.sh"]

EXPOSE 2368
CMD ["npm", "start"]

回答by nwinkler

Let's clear up a couple of things first. When you use both ENTRYPOINTand CMDin a Dockerfile, the CMDvalue is passed to the ENTRYPOINTas a parameter. So what you currently have in the file translates to

让我们先澄清几件事。当您在 Dockerfile 中同时使用ENTRYPOINTCMD时,该CMD值将ENTRYPOINT作为参数传递给。所以你目前在文件中的内容转换为

/entrypoint.sh npm start

This is executed when you start the container. Without knowing what's happening in entrypoint.sh, it's hard to tell what impact this has.

这是在您启动容器时执行的。在不知道 中发生了什么的情况下entrypoint.sh,很难说这有什么影响。

Docker

码头工人

You could make the following changes, please give this a try:

您可以进行以下更改,请尝试一下:

  • Remove the ENTRYPOINTfrom the Dockerfile.
  • Change CMDto the following:

    CMD /wait-for-it.sh localhost && /entrypoint.sh npm start
    
  • 取出ENTRYPOINTDockerfile
  • 更改CMD为以下内容:

    CMD /wait-for-it.sh localhost && /entrypoint.sh npm start
    

When doing that, please adjust the following:

这样做时,请调整以下内容:

  • The path for wait-for-it.sh- please adjust to wherever you're copying the script file in the Dockerfile. I suggest you copy it to the same folder as entrypoint.sh.
  • The localhostargument for the wait-for-it.shscript file, please replace with your database host.
  • 路径wait-for-it.sh- 请调整到您在 Dockerfile 中复制脚本文件的任何位置。我建议您将其复制到与entrypoint.sh.
  • 脚本文件的localhost参数wait-for-it.sh,请替换为您的数据库主机。

What the above does, is run the wait-for-it.shscript and then, once the database is up, it runs the previous command that you had in ENTRYPOINTand CMD. It should be comparable to what you currently have.

上面所做的是运行wait-for-it.sh脚本,然后,一旦数据库启动,它就会运行您在ENTRYPOINT和 中的上一个命令CMD。它应该与您目前拥有的相当。

As an alternative, you could also call the wait-for-it.shscript from your entrypoint.shscript and only run the additional steps (npm startonce the wait script has succeeded). Up to you...

作为替代方案,您也可以wait-for-it.shentrypoint.sh脚本中调用脚本并仅运行附加步骤(npm start等待脚本成功后)。由你决定...

Docker-Compose

Docker-Compose

If you are using Docker-Compose for starting up your containers, you can overwrite the command that is executed when the container starts using the commandattribute in your docker-compose.yamlfile, e.g.

如果您使用 Docker-Compose 来启动容器,则可以使用文件中的command属性覆盖容器启动时执行的命令docker-compose.yaml,例如

command: >
  bash -c "

  /wait-for-it.sh localhost 
  && /entrypoint.sh npm start
  "

Please note the use of

请注意使用

  • bash -cfor starting multiple commands using your shell of choice (Bash in this case)
  • the quotes, you'll need them for having multiple lines.
  • bash -c使用您选择的 shell 启动多个命令(在本例中为 Bash)
  • 引号,您将需要它们来拥有多行。

Using this method, you can basically chain multiple commands to run after each other, combining them using the &&operator.

使用这种方法,您基本上可以将多个命令串联在一起,然后使用&&运算符将它们组合起来。

Wait-for-it Script

等待脚本

BTW: I use this wait-for-it script?for a similar purpose with good results in the same manner as described above. It's slightly more robust than you version of the wait script, and supports pretty much any host/port combination. I use it to wait for MySQL - your question is not clear whether it's about MySQL or PostgreSQL.

顺便说一句:我使用这个等待脚本?用于类似的目的,并以与上述相同的方式获得良好的结果。它比您的等待脚本版本稍微更健壮,并且几乎支持任何主机/端口组合。我用它来等待 MySQL - 你的问题不清楚是关于 MySQL 还是 PostgreSQL。