Have a single Redis
instance set up via docker-compose
(using my Redis Dockerfile
), all working.
Now I’m trying to seed the Redis
instance with data after the container has started.
(1) Trying to run redis-cli
directly in Dockerfile
(that is run by docker-compose
)
FROM redis:6.2.5
COPY ./redis.conf /test_dir/
COPY ./seed.txt /test_dir/
ENTRYPOINT ["redis-server", "/test_dir/redis.conf"]
RUN cat /test_dir/seed.txt | redis-cli -a <password> --pipe
this throws Could not connect to Redis at 127.0.0.1:6379: Connection refused
(2) Slightly different Dockerfile
, running same command in a shell
script that is executed after the container starts:
FROM redis:6.2.5
COPY ./redis.conf /test_dir/
COPY ./seed.txt /test_dir/
COPY ./init.sh /test_dir/
ENTRYPOINT ["redis-server", "/test_dir/redis.conf"]
RUN . /test_dir/init.sh
# init.sh
sleep 10 # ensure Redis server is up and running
cat /test_dir/seed.txt | redis-cli -a <password> --pipe
the shell
script is executed, it waits 10 secs and I confirmed the server was up and running BEFORE the data import was triggered, but Redis
throws the same error.
Notes:
(1) I've also disabled `protected-mode` and removed `requirepass`, but redis-cli can not connect
(2) when I jump into the container and manually execute the command, it DOES WORK !
So how can I run redis-cli
from the Dockerfile
or via shell
script or what is the recommended way to seed a Docker Redis instance ?
Thanks.
3
Answers
this is another solution that works, although @atline solution is more elegant.
Dockerfile
init.sh
This works and uses the provided
redis.conf
, hence it seeds the data into the the.rdb
that you have defined in the config.RUN cat /test_dir/seed.txt | redis-cli -a <password> --pipe
will execute when you dodocker build
, at that timeENTRYPOINT ["redis-server", "/test_dir/redis.conf"]
still not run as it’s only be called when the container start. So, you will surely have error.As a result, you could use next workaround to do it:
/test_dir/seed.txt:
/test_dir/init.sh:
docker-compose.yaml:
Execution:
Explain:
redis-svr
will start a server there in one container,redis-cli
will start another container, it will frist callinit.sh
, theinit.sh
will try to link to redis server to see if server really start or not withredis-cli -h redis-svr -p 6379 quit
. If not, it will wait sometime and retry, if server already start, then it could call the client command to import the initial data to server.EDIT20210912 based on OP’s comment to use one container:
Folder structure:
docker-compose.yaml:
Dockerfile:
init.sh:
my-entrypoint.sh:
Execution:
This define customized entrypoint to let
init.sh
have chance to be executed before redis server run.https://docs.docker.com/config/containers/multi-service_container/
It’s very simple
try mine init.sh