You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker中ioredis连接Redis报getaddrinfo ENOTFOUND错误解决方法

问题描述

从后端服务连接Docker部署的Redis实例时持续抛出DNS解析错误,错误日志如下:

...
api-1    | [ioredis] Unhandled error event: Error: getaddrinfo ENOTFOUND undefined
api-1    |     at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:71:26)
api-1    | [ioredis] Unhandled error event: Error: getaddrinfo ENOTFOUND undefined
api-1    |     at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:71:26)
...
现有配置

Redis客户端代码

import Redis from "ioredis";

export const redisConfig = () => {
  if (process.env.NODE_ENV === "production") {
    return `redis://${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`;
  }
  return "";
};

const redisCli = new Redis(redisConfig());

export default redisCli;

Dockerfile

# ---- Dependencies ---- 

FROM node:16-alpine AS base

# minimize image size
RUN apk add --no-cache libc6-compat 

RUN npm install -g npm@latest

WORKDIR /app

COPY ./package*.json ./

RUN npm ci


# ---- Builder ---- 

FROM node:16-alpine AS builder

RUN npm install -g npm@latest

WORKDIR /app

COPY --from=base /app/node_modules ./node_modules

COPY ./src ./src

COPY package*.json tsconfig.json webpack.config.ts ./

RUN npm run build


# ---- Release ---- 

FROM node:16 AS release

WORKDIR /app

# COPY ./prisma ./prisma 

# COPY ./.env ./

# COPY ./deployment ./deployment

COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./

# RUN npx prisma generate

RUN npm install pm2 -g 

EXPOSE 3000

docker-compose.yml

version: "3"

services:
  api:
    build: ./

    depends_on:
      - redis

    links:
      - redis

    command: sh -c "node dist/server.js"

    environment:
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - NODE_ENV=production

    ports:
      - 3000:3000

  redis:
    image: "redis:latest"
问题根因

报错核心原因是Webpack构建时静态替换了process.env变量:

  • 项目使用Webpack打包后端代码,默认构建目标为web环境,构建阶段会将代码中所有process.env.XXX的访问直接替换为构建时上下文中的对应值。
  • 镜像构建的builder阶段没有传入REDIS_HOST、REDIS_PORT、NODE_ENV等环境变量,因此process.env.REDIS_HOST被直接替换为字面量undefined,最终拼接出的Redis连接地址为redis://undefined:6379。运行时即使容器内注入了正确的环境变量,代码也不会再读取,直接对undefined这个主机名做DNS解析就会抛出ENOTFOUND错误。
  • 配置中的links参数属于Docker早期版本的遗留配置,在v3+版本Compose的默认自定义桥接网络下,服务之间默认可以通过服务名做DNS解析,不是导致本次问题的原因。
修复步骤
  • 修改Webpack配置,指定构建目标为Node.js,禁止构建阶段静态替换运行时环境变量:
    在webpack.config.ts中新增如下配置:
export default {
  // 保留原有其他配置
  target: "node", // 声明构建产物运行在Node.js环境
  node: {
    __dirname: false,
    __filename: false
  }
}
  • 优化Redis客户端初始化逻辑,避免隐式默认值和字符串拼接问题,改用对象形式传参更稳妥:
import Redis from "ioredis";

const redisCli = new Redis({
  host: process.env.REDIS_HOST || "127.0.0.1",
  port: Number(process.env.REDIS_PORT) || 6379,
  // 配置了Redis密码的话补充password字段即可
});

export default redisCli;
  • 重新构建镜像时跳过缓存,避免旧构建产物残留,在项目根目录执行如下命令重启服务:
docker compose down
docker compose build --no-cache api
docker compose up -d

内容的提问来源于stack exchange,提问作者retr0327

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 05:45:07