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客户端版本不一致,根源在于架构差异和镜像构建环境:
- Redis客户端API变更:旧版Redis客户端(如
redis@3.x)使用顶级host/port参数,新版客户端(redis@4.x+)改用socket嵌套对象配置连接参数。 - 架构导致的依赖版本差异:M1 Mac是ARM64架构,部分npm包在该架构下会安装特殊分支版本;而EC2 Ubuntu是AMD64架构,依赖版本可能不同。你的项目本地M1环境可能装了新版
redis-store(依赖redis@4.x+),EC2环境则是旧版redis-store(依赖redis@3.x)。 - 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,提问作者신유빈
相关产品推荐
相关产品推荐

