[英]How to check in Docker whether a volume exists and is not empty and run different docker-compose.yml depending on this?
I'm deploying an application with a Dockerfile and docker-compose.我正在部署一个带有 Dockerfile 和 docker-compose 的应用程序。 It loads a model from an AWS bucket to run the application.
它从 AWS 存储桶加载模型以运行应用程序。 When the containers get restarted (not intentionally but because of the cloud provider), it loads again the model from AWS.
当容器重新启动时(不是故意的,而是因为云提供商),它会再次从 AWS 加载模型。 What I would like to achive is storing the model on a persistent volume.
我想要实现的是将模型存储在持久卷上。 In case of a restart, I would like to check whether the volume exists and is not empty and if so run a different docker-compose file which has a different bash command, not loading the model from AWS again.
在重新启动的情况下,我想检查该卷是否存在且不为空,如果是,则运行具有不同 bash 命令的不同 docker-compose 文件,而不是再次从 AWS 加载模型。
This is part of my docker-compose.yml:这是我的 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"
In case of a restart the command would look like this:如果重新启动,命令将如下所示:
command: bash -c "rasa run --model model.tar.gz --endpoints endpoints.yml --credentials credentials.yml --enable-api --cors \"*\" --debug --port 5006"
Note that this请注意,这
--remote-storage aws
--remote-storage aws
was removed.去掉了。
This is my Dockerfile:这是我的 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 . .
I know that I can use this:我知道我可以使用这个:
docker volume ls
to list volumes.列出卷。 But I do not know how to wrap this in a if condition to check whether
但我不知道如何将其包装在 if 条件中以检查是否
- ./models /app/models
exists and is not empty and if it is not empty run a second docker-compose.yml which contains the second modified bash command.存在且不为空,如果不为空,则运行第二个 docker-compose.yml,其中包含第二个修改后的 bash 命令。
You could have an if statement in your bash command to use aws or not depending on the result you get from docker volume ls
using -f name= you can filter based on the volume name and then you can check if its not null and run a different command.您可以在 bash 命令中使用 if 语句来使用 aws,具体取决于您使用 -f name= 从
docker volume ls
获得的结果,您可以根据卷名称进行过滤,然后您可以检查它是否不为空并运行不同的命令。
Note that this command is just an example and I have no idea if it works or not as I don't use bash day -to-day请注意,此命令只是一个示例,我不知道它是否有效,因为我每天都不使用 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
"
I would accomplish this by making the main container command actually be a script that looks to see if the file exists and optionally fills in the command line argument.我将通过使主容器命令实际上是一个脚本来实现这一点,该脚本查看文件是否存在并可选择填充命令行参数。
#!/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 \
...
The first line uses the test (1) shell command to see if the file already exists, and sets the variable MODEL_EXISTS
to yes
if it exists and empty if it does not.第一行使用test (1)shell命令查看文件是否已经存在,存在则设置变量
MODEL_EXISTS
为yes
,不存在则为空。 Then in the command, there is a shell parameter expansion: if the variable MODEL_EXISTS
is unset or empty :-
then expand and split the text --remote-storage aws
.然后在命令中,有一个 shell 参数扩展:如果变量
MODEL_EXISTS
未设置或为空:-
然后扩展并拆分文本--remote-storage aws
。 (This approach inspired by BashFAQ/050 .) (这种方法受到BashFAQ/050的启发。)
In your Dockerfile, COPY
this script into your image and make it be the default CMD
.在您的 Dockerfile 中,将此脚本
COPY
到您的图像中,并使其成为默认的CMD
。 It needs to be executable like any other script (run chmod +x
on your host and commit that change to source control);它需要像任何其他脚本一样可执行(在您的主机上运行
chmod +x
并将更改提交到源代码管理); since it is executable and begins with a "shebang" line, you do not need to explicitly name the shell when you run it.因为它是可执行的并且以“shebang”行开头,所以在运行它时不需要明确命名 shell。
...
COPY rasa-run ./
CMD ["./rasa-run"]
In your Compose file, you do not need to override the command:
, change the working_dir:
from what the Dockerfile sets, or change from a couple of Compose-provided defaults.在您的 Compose 文件中,您不需要覆盖
command:
,更改working_dir:
Dockerfile 设置的内容,或更改 Compose 提供的几个默认值。 You should be able to reduce this to你应该能够将其减少到
version: '3.8'
services:
rasa-server:
build: .
volumes:
- ./models:/app/models
More generally for this class of question, I might suggest:更一般地,对于这类问题,我可能会建议:
CMD
to a Compose command:
override;CMD
设置为 Compose command:
覆盖; andCMD
or command:
.CMD
或command:
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.