Node.js Docker环境下Redis连接报错getaddrinfo ENOTFOUND求助
Node.js + Redis Docker Compose部署连接失败问题
错误信息
Error: getaddrinfo ENOTFOUND redis 2024-11-17 13:32:35 at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:107:26) { 2024-11-17 13:32:35 errno: -3008, 2024-11-17 13:32:35 code: 'ENOTFOUND', 2024-11-17 13:32:35 syscall: 'getaddrinfo', 2024-11-17 13:32:35 hostname: 'redis' 2024-11-17 13:32:35 }
Node.js Redis初始化代码
import { createClient, RedisClientType } from "redis"; let redisClient: RedisClientType; export const redisInit = () => { redisClient = createClient({ socket: { port: 6379, host: "redis" }, }); redisClient.on("error", (err) => console.log("Redis client error: ", err)); redisClient.connect().then(async () => { console.log("Redis connected"); }); }
Docker Compose配置
services: my-service: container_name: my-service build: context: . dockerfile: Dockerfile ports: - 5000:5000 depends_on: - redis links: - redis environment: REDIS_HOST: redis REDIS_PORT: 6379 redis: container_name: redis hostname: redis image: "redis/redis-stack:edge" ports: - 6379:6379 - 8001:8001 command: ["redis-server", "--bind", "redis", "--port", "6379"] environment: REDIS_ARGS: "--notify-keyspace-events Ksg" deploy: replicas: 1 restart_policy: condition: on-failure networks: - app-network # Attach Redis to the shared network networks: app-network: external: true
已知情况
- Redis容器已正常启动
- 尝试过修改
createClient连接方式(URL/socket),更换host为localhost/0.0.0.0,问题未解决
排查与解决步骤
1. 修复Docker Compose网络配置(核心问题)
你的my-service容器未加入app-network网络,而Redis容器处于该外部网络中,导致两个容器不在同一网络环境下,无法通过主机名redis解析通信。
修改my-service配置,添加networks字段:
services: my-service: container_name: my-service build: context: . dockerfile: Dockerfile ports: - 5000:5000 depends_on: - redis links: - redis environment: REDIS_HOST: redis REDIS_PORT: 6379 networks: # 新增网络配置 - app-network # redis部分保持不变
2. 确保Redis服务就绪后再连接
depends_on仅保证Redis容器先启动,但不保证Redis服务完成初始化。可以在代码中添加重连逻辑:
import { createClient, RedisClientType } from "redis"; let redisClient: RedisClientType; export const redisInit = async () => { redisClient = createClient({ socket: { port: parseInt(process.env.REDIS_PORT || "6379"), host: process.env.REDIS_HOST || "redis", reconnectStrategy: (retries) => Math.min(retries * 50, 500) // 指数退避重连 }, }); redisClient.on("error", (err) => console.log("Redis client error: ", err)); redisClient.on("connect", () => console.log("Redis connected")); try { await redisClient.connect(); } catch (err) { console.log("Failed to connect to Redis, retrying..."); setTimeout(redisInit, 1000); } }
3. 验证Redis绑定配置
当前Redis启动命令--bind redis仅绑定容器主机名对应的IP,若需要更宽松的访问权限,可改为绑定所有接口:
command: ["redis-server", "--bind", "0.0.0.0", "--port", "6379"]
4. 使用环境变量替代硬编码
将代码中硬编码的连接参数替换为读取环境变量,提升配置灵活性:
socket: { port: parseInt(process.env.REDIS_PORT || "6379"), host: process.env.REDIS_HOST || "redis" }
内容的提问来源于stack exchange,提问作者iman
相关产品推荐
相关产品推荐

