【Docker】通过docker命令行,报错:Fatal error, can't open config file,在容器内执行没问题
首先,我的dockerfile如下:
FROM redis:latestCOPY $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没有任何问题,可以启动成功:
[email protected]:/data# ls -l /root/redis.conf-rwxrwxrwx 1 root root 58765 Sep 3 12:59 /root/redis.conf
[email protected]:/data# redis-server /root/redis.conf8: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:latestCOPY $PWD/redis.conf /root/
CMD ["/usr/local/bin/redis-server", "/root/redis.conf"]
???
回答
用 docker inspect 可以看到,redis 的 docker 镜像的默认的 Entrypoint 是 docker-entrypoint.sh
。也就是说,CMD 定义的命令是由这个脚本执行的。
这个脚本的内容如下(可能不同的版本会有所不同):
#!/bin/shset -e
# first arg is `-f` or `--some-option`
# or first arg is `something.conf`
if [ "${1#-}" != "$1" ] || [ "${1%.conf}" != "$1" ]; then
set -- redis-server "[email protected]"
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" "[email protected]"
fi
exec "[email protected]"
可以看到,当 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
。
- 是因为启动的时候的用户是 redis ,redis 用户读取 /root/ 目录没有权限
docker run -it --rm 7141cd2da206 bash
进入容器后使用的用户是 root,所以能够读取配置- 绝对路径, 原因还不知道为什么,但是通过查看运行程序的用户, 当使用绝对路径时 使用 root 用户启动的
下面是两次启动的命令和用户
哇,看不懂一大坨
我也遇到了同样的问题,貌似相对路径会找不到文件
改成绝对路径就可以了
但是我把 redis.conf 挂载到 /tmp 目录下,依然提示无法读取; /tmp 目录是777权限
以上是 【Docker】通过docker命令行,报错:Fatal error, can't open config file,在容器内执行没问题 的全部内容, 来源链接: utcz.com/a/73977.html