连接到 Redis Docker 实例时出现“错误:连接超时”

问题描述 投票:0回答:1

我正在 Docker 容器内运行我的 Node/Express 应用程序,并通过 Docker Compose 与 Redis 实例连接在一起。问题是,当我尝试将 Node 应用程序与 Redis 连接时(使用 this npm package,v^4.0.1),我收到此错误:

Error: Connection timeout
     at Socket.<anonymous> (/app/node_modules/@node-redis/client/dist/lib/client/socket.js:163:124)
     at Object.onceWrapper (node:events:509:28)
     at Socket.emit (node:events:390:28)
     at Socket.emit (node:domain:537:15)
     at Socket._onTimeout (node:net:501:8)
     at listOnTimeout (node:internal/timers:557:17)
     at processTimers (node:internal/timers:500:7)

如果我使用

docker run --name my-redis -p 6379:6379 -d redis
运行单独的 Redis 实例,并且使用
127.0.0.1:6379
作为 Node 中的连接 URL,则它可以工作。所以我认为这与 Docker 网络有关,但我找不到什么。

这是我的 docker-compose.yaml:

version: "3.9" 
services:
  api:
    build: .
    volumes:
      - ./src/:/app/src/
    ports:
      - "8080:8080"
    environment:
      - NODE_ENV
  redis:
    image: "redis:6.2.6"

这是 Node 应用程序的 Dockerfile:

# base image
FROM node:16.13.0-alpine

# working directory
WORKDIR /app

# add binaries to $PATH
ENV PATH /app/node_modules/.bin:$PATH

# install and cache app dependencies
COPY package*.json ./
RUN npm install

# copy app files and build
COPY . .
RUN npm run build

# start app
CMD [ "npm", "start", "--ENV=${NODE_ENV}" ]

这是我在 Node 应用程序中用于连接到 Redis 的代码:

import { createClient } from "redis";    

(...)    

const client = createClient({ url: `redis://redis:6379` });

client.on("error", (error) => {
  throw error;
});

await client.connect();
const data = await client.get(customerId);
await client.quit();
return data;

请问有什么帮助吗?

非常感谢!

node.js docker express docker-compose redis
1个回答
0
投票

我通过将 redis.connect() 函数调用移到顶级代码之外解决了这个问题。

我正在使用最新版本的 npm Redis (7.2.4) 和官方 docker redis 镜像 (7.2.4)。我相信我们的设置比较相似。

setup.js

const { createClient } = require("redis");

const client = createClient({
  url: "redis://<<the-name-of-your-redis-service-in-docker-compose>>:6379",
});


async function setupRedis() {
  await client.connect();
  console.log("Connected to Redis");
}

async function mySetupFunctions() {
    await setupRedis();
}

index.js

... // express node setup
// (this is in the top-level code)
const { setupFunction } = require("./setup.js"); // 
// Import the function and run it
setupFunction();
...

compose.yml

version: "3.8"

services:
  api:
    build:
      dockerfile: Dockerfile.dev // this is my Dockerfile for my Node container
      context: ./backend // This is my Node.js container
  cache: // this is the name of my redis service but it can be changed to anything. The name of the service should be reflected in the redis URL as mentioned in the setup.js code snippet.
    image: redis
    depends_on:
      - api

我无法真正谈论该解决方案的技术细节,因为我对开发还很陌生,但我希望这可以帮助别人!

© www.soinside.com 2019 - 2024. All rights reserved.