redis docker在docker compose的localhost上不可用

kcrjzv8t  于 2021-06-09  发布在  Redis
关注(0)|答案(1)|浏览(600)

我现在遇到了一个问题,我想解决一个多星期,但我一事无成。我希望你能给我指出正确的方向。

初始情况

说明

我正在构建的项目是一个nestjs应用程序,它连接到一些api。在内部,它使用bullmq作为消息队列,消息队列本身使用ioredis连接到redis数据库。我已经连接了我自己编写的服务器组件以及redis(它使用docker)通过 docker-compose up 具有以下配置:

version: '3'

services:
  server:
    image: myserver:1.4.0
    container_name: myserver
    depends_on:
      - db
    ports:
      - 3001:3000
    environment:
      - REDIS_HOST=redis
  db:
    image: redis:6.0.8
    container_name: redis
    ports:
      - 6379:6379

版本

工作站

docker版本19.03.13,内部版本4484c46d9d
docker compose版本1.27.4,内部版本40524192

服务器组件

bullmq 1.9.0版
ioredis 4.17.3

redis docker公司

6.0.8

问题

我的服务器组件的问题是,它试图使用以下代码连接到端口6379处给定redis\u主机下的redis示例:

readonly connection = new Redis(
    +(process.env.REDIS_PORT ?? this.configService.get('redis_port')),
    process.env.REDIS_HOST ?? this.configService.get('redis_host'),
  );

但抛出以下错误:

[ioredis] Unhandled error event: Error: connect ECONNREFUSED 127.0.0.1:6379

我希望它只看到暴露端口上的redis示例。
因此,它在127.0.0.1中没有看到redis示例:但是它不应该使用给定的ip吗?

我查过的东西

服务器代码正确,在ioredis调用中正确提交和调用redis\u主机。所以我在ioredis内部进一步挖掘发现了这个问题。所以,它应该是可用的,因为所有的提示在我的工作站本地,我用0.0.0.0:6379连接,它工作得很好。
docker compose会自动创建网桥,使用netcat i checked,redis docker ip上的端口6379(以及别名redis&db),可以从server dockers控制台获得redis示例。
然后,我使用docker compose的网络配置明确地设置子网,并为容器提供静态ip,但正如我已经描述的:ip已正确解析。
我在docker github 204版上发现了以下问题。我想这正是我在这里面临的问题,但如何解决呢?
热释光;dr ioredis尝试连接到正确解析的redis示例的ip,但是失败了,因为该示例在服务器组件的本地ip上不可用。

我现在的状态是什么

我无法控制地抽泣。
我目前不知道如何让“myserver”容器通过ioredis连接到redis示例。我的观点是,我遇到的问题必须与windows上docker将ips解析为127.0.0.1的方式有关。
我的观点对吗?
你还可以建议用什么方法试试?
致以最诚挚的问候和感谢。
编辑(2020-11-27):经过一些挖掘和进一步调查杰弗里·米克森的建议,不幸的是,我还没有接近一个解决方案。我最后的步骤包括:
更新所有依赖项(包括将MQ更新到v1.11,将ioredis更新到4.19.2)。这并没有改变什么。
然后,我在bullmq发布板上发现了一篇关于类似问题的相对较新的帖子,我从在上面所示的连接对象中重用连接切换到始终创建一个新连接,正如bullmq文档中所解释的那样。但这也无济于事。

new Queue(name, {
        connection: {
          host: this.redisHost,
          port: this.redisPort,
        },
      })

然后我从使用ioredis库中的redis对象切换到ioredis对象,但是仍然没有改变我的应用程序docker的习惯。即使redis主机正确地调用了redis连接,它仍然尝试连接到127.0.0.1:6379,如上图所示。
最后,奇怪的行为,例如,如果我选择了一个无法解析的主机url,应用程序docker会正确地尝试连接到这个无法解析的主机。但一旦docker compose的网络中有了这个主机,它就使用127.0.0.1。
编辑(2020-12-01):与此同时,我在一台干净的linux机器上检查了这个问题是否只会发生在docker for windows上,但它也会发生在linux上。
我没有解决问题本身,但我绕过了它,我只是把一切都放在一个码头。由于我的应用程序更多的是一个概念证明,所以这样做没有什么大的痛苦。如果将来有一个解决方案,或者有更多的人有同样的问题,我会把这个问题留待讨论。
对于那些想知道,我的dockerfile包括redis现在堆叠在redis图像上的另一层。我正在添加我以前使用的ng-cli-e2e映像的部分。因此,在我现有的dockerfile的开头,我添加了:

FROM redis:6.0.9-buster

RUN apt update

RUN apt install nodejs -y

RUN apt install npm -y

最后,我创建了一个小的 Package 器脚本,它只启动redis服务器和我的应用程序。我现在还公开了两个端口,如果我想从我的机器访问所有东西的话。

EXPOSE 3000 6379

CMD ./docker-start-wrapper.sh

这不是最好的解决方案,但目前确实有效。

fd3cxomn

fd3cxomn1#

问题是应用程序容器使用localhost作为连接到redis容器的主机名。在这种情况下,它应该使用主机名redis。
考虑以下演示:

version: '3.7'

services:
  server:
    image: busybox
    container_name: myserver
    entrypoint: /bin/sh
    # if redis is replaced by localhost or 127.0.0.1 below, this container will fail
    command: "-c \"sleep 2 && nc -v redis 6379\""
    depends_on:
      - db
    ports:
      - 3001:3000
    environment:
      - REDIS_HOST=redis
  db:
    image: busybox
    container_name: redis
    entrypoint: /bin/nc
    command: "-l -p 6379 -v"
    # is not necessary to publish these ports
    #ports:
    #  - 6379:6379
$ docker-compose -f scratch_2.yml up
Creating network "scratches_default" with the default driver
Creating redis ... done
Creating myserver ... done
Attaching to redis, myserver
redis     | listening on [::]:6379 ...
myserver  | redis (172.25.0.2:6379) open
redis     | connect to [::ffff:172.25.0.2]:6379 from [::ffff:172.25.0.3]:34821 ([::ffff:172.25.0.3]:34821)
myserver exited with code 0
redis exited with code 0

发布端口时,它们将在主机上的容器外部使用。通过尝试连接 mysever 容器到 127.0.0.1 ,容器只是尝试连接到自身。

相关问题