通过docker命令行,报错:Fatal error, can't open config file,在容器内执行没问题

发布于 2022-09-11 22:42:43 字数 3140 浏览 15 评论 0

首先,我的dockerfile如下:

FROM redis:latest
COPY $PWD/redis.conf /root/
RUN ["chmod", "777", "/root/redis.conf"]
CMD ["redis-server", "/root/redis.conf"]

redis.conf文件的内容是从这里复制的https://raw.githubusercontent...

使用docker build .之后,使用docker run -it --rm 7141cd2da206运行,
报以下错误:

1:C 03 Sep 2019 12:59:48.539 # Fatal error, can't open config file '/root/redis.conf'

但是,我通过bash进入容器:docker run -it --rm 7141cd2da206 bash
执行redis-server没有任何问题,可以启动成功:

root@7d50439a05df:/data# ls -l /root/redis.conf 
-rwxrwxrwx 1 root root 58765 Sep  3 12:59 /root/redis.conf
root@7d50439a05df:/data# redis-server /root/redis.conf 
8:C 03 Sep 2019 13:05:46.070 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
8:C 03 Sep 2019 13:05:46.070 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=8, just started
8:C 03 Sep 2019 13:05:46.070 # Configuration loaded
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 5.0.5 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 8
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

8:M 03 Sep 2019 13:05:46.072 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
8:M 03 Sep 2019 13:05:46.073 # Server initialized
8:M 03 Sep 2019 13:05:46.073 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
8:M 03 Sep 2019 13:05:46.073 * Ready to accept connections

很困惑啊。。。!!

-----更新------

把dockerfile里redis-server替换成绝对路径又可以了:

FROM redis:latest
COPY $PWD/redis.conf /root/
CMD ["/usr/local/bin/redis-server", "/root/redis.conf"]

???

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

哥,最终变帅啦 2022-09-18 22:42:43

docker inspect 可以看到,redis 的 docker 镜像的默认的 Entrypoint 是 docker-entrypoint.sh 。也就是说,CMD 定义的命令是由这个脚本执行的。

这个脚本的内容如下(可能不同的版本会有所不同):

#!/bin/sh
set -e

# first arg is `-f` or `--some-option`
# or first arg is `something.conf`
if [ "${1#-}" != "$1" ] || [ "${1%.conf}" != "$1" ]; then
        set -- redis-server "$@"
fi

# allow the container to be started with `--user`
if [ "$1" = 'redis-server' -a "$(id -u)" = '0' ]; then
        find . \! -user redis -exec chown redis '{}' +
        exec gosu redis "$0" "$@"
fi

exec "$@"

可以看到,当 CMD 的第一个元素为 redis-server 的时候,它将当前目录(WorkingDir,通过 docker inspect 可以看到是 /data) 的所有文件的所有者改为了 redis ,然后以 redis 用户运行命令。

Dockerfile 里,虽然将 /root/redis.conf 的权限改成了 777 ,但是 /root 目录的权限是 700 ,redis 用户不可读,于是出错。将 /root 的权限也改成 777 就可以解决。

========================

由于脚本在进行精确匹配,命令改为绝对路径后将不能匹配,会进入最后一行的 exec 。此时是用 root 用户跑的,所以有读权限,可以启动。

或者说,只要 CMD 的第一个元素不是 redis-server ,那么用户就是 root 。所以用 bash 进容器里再跑也是没有问题的。

最后,如果 CMD 改成: CMD redis-server /root/redis.conf ,这个 CMD 会被改写成:CMD ["/bin/sh", "-c", "redis-server /root/redis.conf"] 。参考 Dockerfile / CMD 文档 ,并且可以通过 docker inspect 看到实际的 Cmd 。这时,运行的用户也是 root ,也是有读权限的,可以运行。

在命令行指定 CMD 也会使用同样的规则,参考 docerker run / COMMAND 文档 , 可以解释 @cai2h 的问题。

======================

如果 CMD 的第一个参数以 - 开始,或者以 .conf 结束,那么 docker-entrypoint.sh 会在前面加一个 redis-server 。这是其中第一个 if 干的事情。此时,由于第一个参数是(新插入的)redis-server ,所以也会以 redis 用户运行。

也就是说,启动 redis 镜像时,redis-server 命令其实可以不写,只写参数。比如:CMD ["/root/redis.conf"] 。或者,docker run -it --rm a7f182f6c6dd /root/redis.conf

玩世 2022-09-18 22:42:43
  1. 是因为启动的时候的用户是 redis ,redis 用户读取 /root/ 目录没有权限
  2. docker run -it --rm 7141cd2da206 bash 进入容器后使用的用户是 root,所以能够读取配置
  3. 绝对路径, 原因还不知道为什么,但是通过查看运行程序的用户, 当使用绝对路径时 使用 root 用户启动的

下面是两次启动的命令和用户

clipboard.png

沫离伤花 2022-09-18 22:42:43

哇,看不懂一大坨

眼泪淡了忧伤 2022-09-18 22:42:43

我也遇到了同样的问题,貌似相对路径会找不到文件
clipboard.png
改成绝对路径就可以了
clipboard.png

森林迷了鹿 2022-09-18 22:42:43

但是我把 redis.conf 挂载到 /tmp 目录下,依然提示无法读取; /tmp 目录是777权限

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文