【问题标题】:How to run command conditionally in docker compose如何在 docker compose 中有条件地运行命令
【发布时间】:2019-10-25 03:21:59
【问题描述】:

我想在 docker-compose 中有条件地运行命令

因为当有人第一次运行这个应用程序时,

他们必须运行migrate 命令才能正确运行django 应用程序

但如果他们的 docker 已经运行了migrate,则无需再次运行migrate

所以这是检查他们的 docker 是否已运行 migrate 的命令。

    if [[ -z $(python3 zeus/manage.py showmigrations | grep '\[ \]')]]; then
        echo 'no need to migrate'
    else
        echo 'need to migate'
    fi

这是我的 docker-compose。

version: '3'

services:
  db:
    image: postgres
  web:
    command: >
         bash -c "if [[ -z $(python3 zeus/manage.py showmigrations | grep '\[ \]')]]; then
               echo 'no need to migrate'
            else
               echo 'need to migate'
            fi && python3 zeus/manage.py runserver 0.0.0.0:8000
         "

但是会出现这样的错误

ERROR: Invalid interpolation format for "build" option in service 
"web": "bash -c "if [[ -z $(python3 zeus/manage.py showmigrations | grep '\[ \]')]]; then 
echo 'no need to migrate' else echo 'need to migate' fi 
&& python3 zeus/manage.py runserver 0.0.0.0:8000""

有什么想法吗?

编辑

当我在普通 bash 中运行检查迁移的脚本时,这很好

我认为 docker-compose 无法解析 $(python3 manage.py .....) 部分。

【问题讨论】:

  • 添加一个shebang,然后将你的bash脚本粘贴到那里:shellcheck.net
  • 当我在 bash 中运行该脚本时,这很好。但是,该错误发生在 docker-compose.yml
  • 首先你需要在最后一个]]之前添加一个sapce

标签: bash docker syntax docker-compose dockerfile


【解决方案1】:

试试这个:

version: '3'

services:
  db:
    image: postgres
  web:
    command: bash -c "if [[ -z $$(python3 zeus/manage.py showmigrations | grep '\\[ \\]') ]]; then
               echo 'no need to migrate';
            else
               echo 'need to migate';
            fi && python3 zeus/manage.py runserver 0.0.0.0:8000"

存在三个问题,您需要转义转义字符 \ 并添加更多 $ 以转义 compose 中的替换,并在最后一个 ]] 之前多留一个空格

【讨论】:

  • 没有像this Invalid interpolation format for "build" option in service那样出现错误,而是像web_1 | bash: -c: line 1: syntax error: unexpected end of file这样出现
  • 但这对我来说不是运气。我可以分享我的撰写文件的代码。 github.com/RayKimEX/docker-compose-stackover-flow/blob/master/…
  • 无论如何,我很欣赏答案。它帮助到我。谢谢
  • 没有发生错误,但会打印类似no need to migrate else echo need to migate的消息。它似乎不适用于if statements
  • 等等 ";"在echo 'no need to migrate' 之后:D
【解决方案2】:

尽量避免在 docker-compose.yml 中编写复杂的脚本,尤其是当它们用于应用程序设置的正常部分时。

典型的模式是将这种设置放在入口点脚本中。该脚本以 shell 命令exec "$@" 结束。在 Docker 上下文中,这告诉它用命令替换自己(来自 Dockerfile CMD 语句或 Docker Compose command:)。对于您的示例,这可能看起来像

#!/bin/sh
if [ -z $(python3 zeus/manage.py showmigrations | grep '\[ \]')]; then
    echo 'no need to migrate'
else
    echo 'need to migate'
fi
exec "$@"

然后在你的 Dockerfile 中,复制这个文件并将其指定为ENTRYPOINT;不修改运行您的应用程序的 CMD

COPY entrypoint.sh /app
RUN chmod +x entrypoint.sh
ENTRYPOINT ["/app/entrypoint.sh"]
CMD python3 zeus/manage.py run --host=0.0.0.0:8000

ENTRYPOINT 语句必须是 JSON 数组形式,并且其中不能有显式的 sh -c 包装器。

如果你想验证设置是否正确,你可以运行

docker-compose run web sh

您将在exec "$@" 的位置获得一个shell:在您的迁移和其他设置运行之后,而不是您的主服务器进程。

【讨论】:

  • 我在 Dockerfile 中尝试了这个脚本。但是 Dockerfile 无法识别 compose 中定义的主机名称 db。所以我无法运行migrate 的命令,因为。 migrate命令与主机名有关系db
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-08
  • 2016-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-08
相关资源
最近更新 更多