[英]Dockerfile not copying file to image - no such file or folder
What I am trying to achieve:我想要达到的目标:
This way, I can have multiple redis instances setup for local dev, staging and production environments.这样,我可以为本地开发、暂存和生产环境设置多个 redis 实例。
I have the following folder structure:我有以下文件夹结构:
/redis
--.env
--Dockerfile
--redis.conf
This is the Dockerfile:这是 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.
当我go到redis文件夹运行
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:一切都按预期构建,但是当我执行
docker run -dp 6379:6379 redis-test
之后容器崩溃并出现以下错误:
Fatal error, can't open config file '/data/redis-server redis.conf': No such file or directory
致命错误,无法打开配置文件“/data/redis-server redis.conf”:没有这样的文件或目录
It seems that the redis.conf file from my folder is not getting correctly copied to my image?我文件夹中的 redis.conf 文件似乎没有正确复制到我的图像中? But the
envsubst
runs as expected so it seems that the file is there and the.env variables get overwriten as expected?但是
envsubst
按预期运行所以似乎文件在那里并且 .env 变量按预期被覆盖?
What am I doing wrong?我究竟做错了什么?
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.直接的错误是您明确地将
CMD
作为单个单词放置,因此它被解释为包含空格而不是可执行文件和参数的可执行文件名。 Split this into two words:将其拆分为两个词:
CMD ["redis-server", "redis.conf"]
There's a larger and more complex problem around when envsubst
gets run.运行
envsubst
时会出现更大更复杂的问题。 You're RUN
ning it as part of the image build, but that means it happens before the container is run and the environment variables are known.您正在
RUN
它作为映像构建的一部分,但这意味着它发生在容器运行并且环境变量已知之前。
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.
它作为主容器进程运行,因此在 Docker 级容器设置发生后,它可以看到所有容器环境变量。 It can run
envsubst
or whatever other first-time setup is required, and then run exec "$@"
to invoke the normal container command.它可以运行
envsubst
或任何其他需要的首次设置,然后运行exec "$@"
来调用正常的容器命令。
#!/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
.使此脚本在主机上可执行 (
chmod +x entrypoint.sh
),将其COPY
到您的图像中,并将其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"]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.