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

Nest.js对接Docker Redis时跨系统配置差异致ECONNREFUSED错误原因咨询

Nest.js Redis缓存跨环境(M1 Mac/Ubuntu EC2)连接配置差异原因解析

问题背景

开发Nest.js项目时用Redis做缓存管理器,在本地M1 iMac的Docker环境和Ubuntu 22.04 EC2的Docker环境中,必须用不同的CacheModule配置才能连接Redis,否则会抛出连接拒绝错误:

Error: connect ECONNREFUSED 127.0.0.1:6379 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1555:16)

两边docker-compose.yml配置完全一致(相同网络、容器名、主机名),但有效配置不同:

  • M1 iMac环境:必须通过socket嵌套对象配置主机和端口
// M1 iMac 有效配置
CacheModule.register({
  store: redisStore,
  socket: { host: "redis", port: 6379 },
}),
  • Ubuntu 22.04 EC2环境:必须直接使用顶级host和port属性
// Ubuntu 22.04 有效配置
CacheModule.register({
  store: redisStore,
  host: "redis",
  port: 6379,
}),

已通过环境变量适配解决,但找不到官方说明,需明确原因。

我的配置与解决方案

docker-compose.yml

version: "3.8"
services:
  redis:
    image: redis:latest
    container_name: redis
    ports:
      - 6379:6379
    volumes:
      - redis:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 1s
      timeout: 2s
      retries: 10
    networks:
      - samplenetwork
  web:
    image: shinyubin/fow-be:latest
    container_name: fow-be
    restart: always
    ports:
      - "5000:5000"
    volumes:
      - .:/usr/src/app
      - /usr/src/app/node_modules
    environment:
       - ENVIRONMENT=production
    networks:
      - samplenetwork
    depends_on:
      - redis
volumes:
  redis:
    driver: local
networks:
  samplenetwork:

环境适配代码

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    CacheModule.registerAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => {
        const environment = configService.get<string>("ENVIRONMENT");
        const redisConfig =
          environment === "production"
            ? {
                store: redisStore,
                host: "redis",
                port: 6379,
              }
            : {
                store: redisStore,
                socket: { host: "redis", port: 6379 },
              };
        return {
          ...redisConfig,
        };
      },
      inject: [ConfigService],
    })
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

原因解析

这种差异核心是redis-store依赖的Redis客户端版本不一致,根源在于架构差异和镜像构建环境:

  1. Redis客户端API变更:旧版Redis客户端(如redis@3.x)使用顶级host/port参数,新版客户端(redis@4.x+)改用socket嵌套对象配置连接参数。
  2. 架构导致的依赖版本差异:M1 Mac是ARM64架构,部分npm包在该架构下会安装特殊分支版本;而EC2 Ubuntu是AMD64架构,依赖版本可能不同。你的项目本地M1环境可能装了新版redis-store(依赖redis@4.x+),EC2环境则是旧版redis-store(依赖redis@3.x)。
  3. Docker镜像的依赖差异:如果shinyubin/fow-be:latest镜像是在AMD64环境构建的,里面的redis-store版本和本地M1环境安装的不一致,导致配置要求不同。

验证与统一方案

  • 分别在本地和EC2环境执行npm list redis redis-store,对比两个环境的依赖版本。
  • 在package.json中明确锁定redis和redis-store的版本(比如指定redis@4.x及对应兼容的redis-store版本),这样两边就能用相同的socket配置方式,无需区分环境。

内容的提问来源于stack exchange,提问作者신유빈

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:19:52