简体   繁体   English

Dockerfile 不将文件复制到图像 - 没有这样的文件或文件夹

[英]Dockerfile not copying file to image - no such file or folder

What I am trying to achieve:我想要达到的目标:

  1. copy a redis.config template to my docker image将 redis.config 模板复制到我的 docker 图像
  2. read.env variables content and replace the template variables references (such as passwords, ports etc.) with values from.env读取.env 变量内容并将模板变量引用(例如密码、端口等)替换为来自.env 的值
  3. start the redis-server with the prepared config file使用准备好的配置文件启动 redis-server

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM