在Docker Compose中使用Redis:是否有一种方式可以指定redis.conf文件?

65

我的 Redis 容器在 docker_compose.yml 文件中被定义为标准镜像。

redis:  
  image: redis
  ports:
    - "6379"

我猜它正在使用标准设置,比如将Redis绑定到本地主机。 我需要将它绑定到0.0.0.0,有没有办法添加一个本地的redis.conf文件来改变绑定并让docker-compose使用它?

感谢任何技巧...


非常重要的是,如果您自定义了redis.conf文件,则需要绑定0.0.0.0 -::1,否则无论您遵循下面哪个答案,它都不起作用。在撰写本文之前,我尝试了所有这些方法。 - PirateApp
8个回答

64

是的。只需通过卷将您的redis.conf挂载到默认配置上:

redis:  
  image: redis
  volumes:
    - ./redis.conf:/usr/local/etc/redis/redis.conf
  ports:
    - "6379"

或者,基于redis镜像创建一个新的镜像,并将你的配置文件复制进去。完整的说明在:https://registry.hub.docker.com/_/redis/

然而,默认情况下,redis镜像绑定的是0.0.0.0。要从主机访问它,你需要使用Docker为你映射到主机的端口,你可以使用docker ps或者docker port命令查找到该端口,并通过localhost:32678来访问它,其中32678是映射的端口。另外,你也可以在docker-compose.yml中指定一个特定的端口进行映射。

由于您似乎还不熟悉Docker,如果您首先使用原始的Docker命令而不是使用Compose可能会更加容易理解上述内容。


1
非常感谢...我之前已经学过Docker的命令了...现在我正在学习Compose...我会尝试两个建议... - user762579
10
我尝试按照你的建议操作,但Redis没有读取我的配置文件,似乎只是加载了自己默认的配置文件;例如,我在配置文件中设置了密码,但是当实例运行时,并没有要求输入密码。请问可能出了什么问题? - Kousha
1
我做了这个:http://stackoverflow.com/questions/32404425/docker-compose-redis-with-custom-conf-file 如果你能帮我解决问题,我会非常感激。 - Kousha
3
值得注意的是,在这种情况下,您仍然会在控制台看到警告,提示您正在使用默认配置文件。这让我感到困惑,花了一些时间才意识到我实际上正在使用我的自定义配置文件。 - smur89
2
@Kousha - 请参考Marcola的回答。你需要设置命令,否则在启动时无法加载/usr/local/etc/redis/redis.conf。 - Stevey
显示剩余2条评论

56

虽然这是一个旧问题,但如果仍有人想要这样做,可以通过使用卷和命令来实现:

command: redis-server /usr/local/etc/redis/redis.conf
volumes:
 - ./redis/redis.conf:/usr/local/etc/redis/redis.conf

1
如果容器在另一台主机上,这个方法还能行得通吗?卷挂载目录是在主机上的,对吧? - Andreas Wederbrand
值得注意的是,Redis 配置默认只允许来自 127.0.0.1 的连接,因此如果您想从主机连接进行测试,则需要调整选项。 - user2964500
2
Volumes中指定绝对路径映射更加安全,像这样:`volumes:
  • ${PWD}/redis/redis.conf:/usr/local/etc/redis/redis.conf`
- Jinsong Li

29

很不幸,使用Docker时,Redis配置文件变得有点棘手,而被投票选为最佳答案的回答(我敢肯定是来自那些实际上并没有测试过的人)是不起作用的。

但是这个方法确实有效,快速且不费力:

 command: redis-server --bind redis-container-name --requirepass some-long-password --maxmemory 256mb --maxmemory-policy allkeys-lru --appendonly yes
你可以在yaml docker文件的命令部分传递所有变量选项,只需在其前面添加“--”,后跟变量值即可。
永远不要忘记设置密码,并尽可能关闭6379端口。
以后再感谢我。
PS:如果你注意到命令中我没有使用典型的127.0.0.1,而是使用了redis容器名称。这是因为Docker通过其嵌入式DNS服务器在内部分配IP地址。换句话说,此绑定地址变得动态,因此增加了额外的安全层次。
如果你的redis容器名为“redis”,并且你执行命令docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis(用于验证正在运行的容器的内部IP地址),那么就像Docker所说的那样,该命令将被内部转换为类似以下内容:redis-server --bind 172.19.0.5 --requirepass some-long-password --maxmemory 256mb --maxmemory-policy allkeys-lru --appendonly yes

2
这是正确的答案。我花了半天时间尝试各种配置,最终发现在cmd中传递选项是唯一可靠且一致工作且不需要大量额外配置的方法。唯一的问题是我现在选择感谢你而不是以后 :-D 谢谢! - struensee
1
在生产环境中使用 requirepass some-long-password 是一个很大的安全问题。ps 命令会列出你的密码,而 redis-cli 甚至会有一个警告,指出密码已经暴露了 *"Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe."*。在生产环境中一定要使用 redis.conf - Christos Lytras

7

基于David的回答,但更符合"Docker Compose"方式的是:

redis:
  image: redis:alpine
    command: redis-server --include /usr/local/etc/redis/redis.conf
    volumes:
      - ./redis/redis.conf:/usr/local/etc/redis/redis.conf

那么,您可以通过docker-compose.yml文件包含.conf文件,而无需使用自定义镜像。

1
在我的项目中使用它时,我注意到我还必须将绑定键配置为我正在使用的容器名称,如:bind cachebind [your-container-name] - bessa3301

5
  1. 挂载您的配置文件 /usr/local/etc/redis/redis.conf
  2. 添加执行命令以使用您的配置文件启动 redis-server
  redis:
    image: redis:7.0.4-alpine
    restart: unless-stopped
    volumes:
      - ./redis.conf:/usr/local/etc/redis/redis.conf
    command: redis-server /usr/local/etc/redis/redis.conf
    ########################################
    # or using command if mount not work
    ########################################
    command: >
      redis-server --bind 127.0.0.1
      --appendonly no
      --save ""
      --protected-mode yes

3

这是一个老问题,但我有一个看起来很优雅的解决方案,我不需要每次执行命令 ;).

1. 创建 Dockerfile:

#/bin/redis/Dockerfile
FROM redis
CMD ["redis-server", "--include /usr/local/etc/redis/redis.conf"]

我们所做的是告诉服务器将该文件包含在Redis配置中。您在此输入的设置将覆盖默认的Redis设置。
2. 创建您的docker-compose文件。
redisall:
      build:
        context: ./bin/redis
      container_name: 'redisAll'
      restart: unless-stopped
      ports:
        - "6379:6379"
      volumes:
        - ./config/redis:/usr/local/etc/redis

3 创建配置文件,必须与Dockerfile同名。

//config/redis/redis.conf
requirepass some-long-password
appendonly yes

################################## NETWORK #####################################

# By default, if no "bind" configuration directive is specified, Redis listens
# for connections from all the network interfaces available on the server.
# It is possible to listen to just one or multiple selected interfaces using
# the "bind" configuration directive, followed by one or more IP addresses.
#
# Examples:
#
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
#
# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
# internet, binding to all the interfaces is dangerous and will expose the
# instance to everybody on the internet. So by default we uncomment the
# following bind directive, that will force Redis to listen only into
# the IPv4 loopback interface address (this means Redis will be able to
# accept connections only from clients running into the same computer it
# is running).
#
# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
# JUST COMMENT THE FOLLOWING LINE.*
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bind 127.0.0.1

 // and all configurations that can be specified
 // what you put here overwrites the default settings that have the
 container

2
我认为如果我在本地分享工作代码将会很有帮助。
redis:
    container_name: redis
    hostname: redis
    image: redis
    command: >
      --include /usr/local/etc/redis/redis.conf
    volumes:
      - ./redis/redis.conf:/usr/local/etc/redis/redis.conf
    ports:
      - "6379:6379"

2

在Docker环境中使用Redis时,我遇到了同样的问题,即Redis无法将数据保存到dump.rdb文件中。问题出在Redis不能读取redis.conf配置文件上,我通过在docker-compose命令中发送所需的配置来解决这个问题,具体命令如下:

redis19:
   image: redis:5.0
   restart: always
   container_name: redis19
   hostname: redis19
   command: redis-server --requirepass some-secret  --stop-writes-on-bgsave-error no --save 900 1 --save 300 10 --save 60 10000


volumes:
  - $PWD/redis/redis_data:/data
  - $PWD/redis/redis.conf:/usr/local/etc/redis/redis.conf
  - /etc/localtime:/etc/localtime:ro

它运行良好。


我更喜欢这个解决方案。 - Rodolfo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接