在启动我的其他应用程序之前,我正在使用等待脚本来检查数据库是否已启动。
#!/bin/bash
set -e
host="$1"
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
我找到了这个脚本 here .
现在我的应用程序容器停止运行,MySQL 已启动 - 正在执行命令
。
所以脚本是成功的(数据库正在运行)但我不清楚如何执行我应用程序的 dockerfile 中的真实 CMD(在脚本之后)。
这是我的 dockerfile 的结尾:
COPY docker-entrypoint.sh /entrypoint.sh
COPY ./wait-for-it.sh wait-for-it.sh
ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 2368
CMD ["npm", "start"]
最佳答案
让我们先搞清楚几件事。当您同时使用 ENTRYPOINT
和 CMD
在 Dockerfile 中,CMD
值传递给 ENTRYPOINT
作为参数。所以你当前在文件中的内容转换为
/entrypoint.sh npm start
这是在您启动容器时执行的。不知道 entrypoint.sh
中发生了什么, 很难说这有什么影响。
docker
您可以进行以下更改,请尝试一下:
- 删除
ENTRYPOINT
来自Dockerfile
. 更改
CMD
到以下内容:CMD /wait-for-it.sh localhost && /entrypoint.sh npm start
执行此操作时,请调整以下内容:
wait-for-it.sh
的路径- 请调整到在 Dockerfile 中复制脚本文件的位置。我建议您将其复制到与entrypoint.sh
相同的文件夹中.localhost
wait-for-it.sh
的参数脚本文件,请替换为您的数据库主机。
上面的操作是运行 wait-for-it.sh
脚本,然后,一旦数据库启动,它就会运行您在 ENTRYPOINT
中的先前命令和 CMD
.它应该与您目前拥有的相当。
作为替代方案,您也可以调用 wait-for-it.sh
来自您的 entrypoint.sh
的脚本脚本并仅运行附加步骤(npm start
一旦等待脚本成功)。由你决定...
Docker-Compose
如果您使用 Docker-Compose 启动容器,您可以使用 command
覆盖容器启动时执行的命令。 docker-compose.yaml
中的属性文件,例如
command: >
bash -c "
/wait-for-it.sh localhost
&& /entrypoint.sh npm start
"
请注意使用
-
bash -c
使用您选择的 shell 启动多个命令(在本例中为 Bash) - 引号,多行时需要它们。
使用这种方法,您基本上可以将多个命令串联在一起运行,使用 &&
组合它们运营商。
等待脚本
顺便说一句:我用这个wait-for-it script以与上述相同的方式用于类似的目的并获得良好的结果。它比您的等待脚本版本稍微更健壮,并且几乎支持任何主机/端口组合。我用它来等待 MySQL - 你的问题不清楚是关于 MySQL 还是关于 PostgreSQL。
关于mysql - 如何在成功等待脚本后启动 docker 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39860969/