簡體   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