如何在Docker Compose中有条件地运行命令

时间:2019-10-25 03:21:59

标签: bash docker syntax docker-compose dockerfile

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

因为有人第一次运行此应用程序,

他们将必须运行migrate命令,以便他们可以正确运行django应用程序

但是,如果他们的码头工人已经运行migrate,则无需再次运行migrate

这是用于检查其泊坞窗是否已运行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 .....)部分。

2 个答案:

答案 0 :(得分: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"

这里存在三个问题,您需要转义转义字符\,并添加更多$来避免替换内容的撰写,并在最后一个]]之前添加一个空格

答案 1 :(得分:0)

尽量避免在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:运行迁移和其他设置之后,而不是您的主服务器进程。