Docker部署Node应用连接Redis报ECONNREFUSED 127.0.0.1:6379错误
问题修复方案
你的配置存在4个直接导致连通性失败的核心问题,按以下步骤修改即可:
1. Redis客户端配置格式不兼容
当前npm默认安装的redis客户端为4.x以上版本,不再支持在createClient参数顶层直接传host、port字段,你写的配置完全不生效,客户端默认会尝试连接容器本地的127.0.0.1:6379,自然无法连通名为cache的Redis容器。另外你代码里调用的log函数未定义,运行时会直接抛引用错误。
将app.js中的Redis初始化和服务启动逻辑替换为以下代码:
const express = require('express') const app = express() const cors = require('cors') const redis = require('redis') const client = redis.createClient({ url: `redis://${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`, legacyMode: true // 依赖旧版回调语法时保留,否则可删除 }) // 必须添加错误监听,否则连接异常会直接导致进程崩溃 client.on('error', (err) => console.error('Redis connection error:', err)) client.on('connect', () => { console.log('Redis connected') }) app.use(cors()) app.use(express.json()) // 等待Redis连接就绪后再启动HTTP服务,避免启动时连接未完成 async function bootstrap() { await client.connect() app.listen(3000, () => { console.log('API service running on port 3000') }) } bootstrap()
2. 服务依赖启动顺序无就绪检查
depends_on配置仅能保证容器的启动顺序,不会等待Redis、PostgreSQL服务完成初始化、可接收连接后再启动API容器。多数情况下Node服务启动速度快于数据库/缓存服务,API启动时会直接收到连接拒绝错误。
修改docker-compose.yml,为有状态服务添加健康检查,并调整依赖触发条件:
version: "3.8" services: db: image: postgres:14.1-alpine restart: always environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=admin ports: - "5432:5432" volumes: - db:/var/lib/postgresql/data - ./db/init.sql:/docker-entrypoint-initdb.d/create_tables.sql # 新增PostgreSQL健康检查 healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 5 cache: image: redis:6.2-alpine restart: always ports: - "6379:6379" command: redis-server --save 20 1 --loglevel warning volumes: - cache:/data # 新增Redis健康检查 healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 api: container_name: api build: context: . depends_on: # 改为等待依赖服务健康检查通过再启动 db: condition: service_healthy cache: condition: service_healthy ports: - 3000:3000 environment: NODE_ENV: production DB_HOST: db DB_PORT: 5432 DB_USER: postgres DB_PASSWORD: admin DB_NAME: postgres REDIS_HOST: cache REDIS_PORT: 6379 # 删除废弃的links配置,自定义网络下服务名可直接解析 volumes: # 修正挂载路径,和Dockerfile工作目录对齐 - ./:/app # 匿名卷挂载容器内依赖目录,避免本地文件覆盖 - /app/node_modules volumes: db: driver: local cache: driver: local
3. 容器路径配置冲突
你的Dockerfile中WORKDIR ./使用了相对路径,会被解析为容器根目录/,后续依赖安装、代码复制都落在根目录,但compose中原来的volume挂载到/src,路径完全不匹配,容器运行时找不到正确的代码和依赖文件。另外API容器不需要暴露Redis的6379端口,冗余配置可删除。
修改Dockerfile内容:
FROM node:16.15-alpine3.14 # 使用绝对路径固定工作目录 WORKDIR /app COPY package.json ./ RUN npm install COPY ./ ./ # 仅暴露API服务自身端口 EXPOSE 3000 # 生产环境建议替换为node ./app.js直接启动,nodemon仅适合开发环境 CMD [ "npm", "run", "serve" ]
4. 重启生效
修改完所有配置后,执行以下命令清理旧容器、重新构建启动:
docker compose down -v docker compose build --no-cache docker compose up -d
启动后可通过docker compose logs api查看日志,确认Redis、数据库连接正常即可。
内容的提问来源于stack exchange,提问作者kzaiwo
相关产品推荐
相关产品推荐

