Home > Back-end >  Dockerfile not copying file to image - no such file or folder
Dockerfile not copying file to image - no such file or folder

Time:01-30

What I am trying to achieve:

  1. copy a redis.config template to my docker image
  2. read .env variables content and replace the template variables references (such as passwords, ports etc.) with values from .env
  3. start the redis-server with the prepared config file

This way, I can have multiple redis instances setup for local dev, staging and production environments.


I have the following folder structure:

/redis
--.env
--Dockerfile
--redis.conf

This is the Dockerfile:

FROM redis:latest

COPY redis.conf ./
RUN apt-get update
RUN apt-get -y install gettext
RUN envsubst < redis.conf > redisconf

EXPOSE $REDIS_PORT

CMD ["redis-server redis.conf"]

When I go to the redis folder and run docker build -t redis-test . everything builds as expected, but when I do docker run -dp 6379:6379 redis-test afterwards the container crashes with the following error:

Fatal error, can't open config file '/data/redis-server redis.conf': No such file or directory

It seems that the redis.conf file from my folder is not getting correctly copied to my image? But the envsubst runs as expected so it seems that the file is there and the .env variables get overwriten as expected?

What am I doing wrong?

CodePudding user response:

The immediate error is that you've explicitly put the CMD as a single word, so it is interpreted as an executable filename containing a space rather than an executable and a parameter. Split this into two words:

CMD ["redis-server", "redis.conf"]

There's a larger and more complex problem around when envsubst gets run. You're RUNning it as part of the image build, but that means it happens before the container is run and the environment variables are known.

I'd generally address this by writing a simple entrypoint wrapper script. This runs as the main container process, so after the Docker-level container setup happens, and it can see all of the container environment variables. It can run envsubst or whatever other first-time setup is required, and then run exec "$@" to invoke the normal container command.

#!/bin/sh
envsubst < redis.conf.tmpl > redis.conf
exec "$@"

Make this script executable on the host (chmod x entrypoint.sh), COPY it into your image, and make that the ENTRYPOINT.

ROM redis:latest

COPY redis.conf.tmpl entrypoint.sh ./
RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive apt-get -y install gettext

ENTRYPOINT ["./entrypoint.sh"]
CMD ["redis-server", "redis.conf"]
  • Related