I’m deploying an application with a Dockerfile and docker-compose. It loads a model from an AWS bucket to run the application. When the containers get restarted (not intentionally but because of the cloud provider), it loads again the model from 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.
This is part of my 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
was removed.
This is my 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
- ./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.
2
Answers
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 it’s not null and run a different command.Note that this command is just an example and I have no idea if it works or not as I don’t use bash everyday.
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.
The first line uses the test(1) shell command to see if the file already exists, and sets the variable
MODEL_EXISTS
toyes
if it exists and empty if it does not. Then in the command, there is a shell parameter expansion: if the variableMODEL_EXISTS
is unset or empty:-
then expand and split the text--remote-storage aws
. (This approach inspired by BashFAQ/050.)In your Dockerfile,
COPY
this script into your image and make it be the defaultCMD
. It needs to be executable like any other script (runchmod +x
on your host and commit that change to source control); since it is executable and begins with a "shebang" line, you do not need to explicitly name the shell when you run it.In your Compose file, you do not need to override the
command:
, change theworking_dir:
from what the Dockerfile sets, or change from a couple of Compose-provided defaults. You should be able to reduce this toMore generally for this class of question, I might suggest:
CMD
to a Composecommand:
override; andCMD
orcommand:
.