繁体   English   中英

如何在 Docker 中检查卷是否存在且不为空,并根据此运行不同的 docker-compose.yml?

[英]How to check in Docker whether a volume exists and is not empty and run different docker-compose.yml depending on this?

我正在部署一个带有 Dockerfile 和 docker-compose 的应用程序。 它从 AWS 存储桶加载模型以运行应用程序。 当容器重新启动时(不是故意的,而是因为云提供商),它会再次从 AWS 加载模型。 我想要实现的是将模型存储在持久卷上。 在重新启动的情况下,我想检查该卷是否存在且不为空,如果是,则运行具有不同 bash 命令的不同 docker-compose 文件,而不是再次从 AWS 加载模型。

这是我的 docker-compose.yml 的一部分:

  rasa-server:
    image: rasa-bot:latest
    working_dir: /app
    build:
      context: ./
      dockerfile: Dockerfile
    volumes:
     - ./models /app/models

    command: bash -c "rasa run --model model.tar.gz --remote-storage aws --endpoints endpoints.yml --credentials credentials.yml --enable-api --cors \"*\" --debug --port 5006" 

如果重新启动,命令将如下所示:

    command: bash -c "rasa run --model model.tar.gz --endpoints endpoints.yml --credentials credentials.yml --enable-api --cors \"*\" --debug --port 5006" 

请注意,这

--remote-storage aws

去掉了。

这是我的 Dockerfile:

FROM python:3.7.7-stretch AS BASE

RUN apt-get update \
    && apt-get --assume-yes --no-install-recommends install \
        build-essential \
        curl \
        git \
        jq \
        libgomp1 \
        vim

WORKDIR /app

RUN pip install --no-cache-dir --upgrade pip

RUN pip install rasa==3.1
RUN pip3 install boto3

ADD . .

我知道我可以使用这个:

docker volume ls

列出卷。 但我不知道如何将其包装在 if 条件中以检查是否

     - ./models /app/models

存在且不为空,如果不为空,则运行第二个 docker-compose.yml,其中包含第二个修改后的 bash 命令。

您可以在 bash 命令中使用 if 语句来使用 aws,具体取决于您使用 -f name= 从docker volume ls获得的结果,您可以根据卷名称进行过滤,然后您可以检查它是否不为空并运行不同的命令。
请注意,此命令只是一个示例,我不知道它是否有效,因为我每天都不使用 bash

command: bash -c "
    VOLUME = docker volume ls -f name=FOO
    if [ -z "$VOLUME" ]; 
    then
        rasa run --model model.tar.gz --remote-storage aws --endpoints endpoints.yml --credentials credentials.yml --enable-api --cors \"*\" --debug --port 5006
    else 
        rasa run --model model.tar.gz --endpoints endpoints.yml --credentials credentials.yml --enable-api --cors \"*\" --debug --port 5006
    fi
    " 

我将通过使主容器命令实际上是一个脚本来实现这一点,该脚本查看文件是否存在并可选择填充命令行参数。

#!/bin/sh

MODEL_EXISTS=$(test -f /app/models/model.tar.gz && echo yes)

exec rasa run \
  --model model.tar.gz \
  ${MODEL_EXISTS:---remote-storage aws} \
  --endpoints endpoints.yml \
  ...

第一行使用test (1)shell命令查看文件是否已经存在,存在则设置变量MODEL_EXISTSyes ,不存在则为空。 然后在命令中,有一个 shell 参数扩展:如果变量MODEL_EXISTS未设置或为空:-然后扩展并拆分文本--remote-storage aws (这种方法受到BashFAQ/050的启发。)

在您的 Dockerfile 中,将此脚本COPY到您的图像中,并使其成为默认的CMD 它需要像任何其他脚本一样可执行(在您的主机上运行chmod +x并将更改提交到源代码管理); 因为它是可执行的并且以“shebang”行开头,所以在运行它时不需要明确命名 shell。

...
COPY rasa-run ./
CMD ["./rasa-run"]

在您的 Compose 文件中,您不需要覆盖command: ,更改working_dir: Dockerfile 设置的内容,或更改 Compose 提供的几个默认值。 你应该能够将其减少到

version: '3.8'
services:
  rasa-server:
    build: .
    volumes:
      - ./models:/app/models

更一般地,对于这类问题,我可能会建议:

  1. 更喜欢将 Dockerfile 默认CMD设置为 Compose command:覆盖;
  2. 在脚本中写出重要逻辑并将该脚本作为主容器命令运行; 不要在内联CMDcommand:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM