Docker Compose下Node.js(TypeORM)无法连接PostgreSQL
Node.js + TypeORM + PostgreSQL Docker Compose 连接失败问题解决
问题描述
编写docker-compose文件连接Node.js(TypeORM)后端与PostgreSQL数据库时,出现connect ECONNREFUSED 127.0.0.1:5432错误。单独运行容器正常,但通过docker-compose服务名连接时失败,使用版本:docker compose 2.24.6、docker 26.0.0。
相关配置文件
Node.js Dockerfile
FROM node:alpine WORKDIR /usr/app COPY package*.json ./ RUN npm install COPY . . EXPOSE 3000 CMD npm start
TypeORM data-source.ts
export const AppDataSource = new DataSource({ type: "postgres", host: "db", port: 5432, username: "admin", password: "mysecretpassword", database: "taskmanagerdb", synchronize: true, logging: false, entities: [User, Task, Category], migrations: [], subscribers: [], })
docker-compose.yml
services: db: image: postgres volumes: - ./data/db:/var/lib/postgresql/data environment: - POSTGRES_DB=taskmanagerdb - POSTGRES_USER=admin - POSTGRES_PASSWORD=mysecretpassword ports: - "5432:5432" server: build: . ports: - "3000:3000" depends_on: - db environment: - PGHOST=db
package.json
{ "name": "TaskManager", "version": "0.0.1", "description": "Awesome project developed with TypeORM.", "devDependencies": { "@types/express": "^4.17.21", "@types/node": "^16.11.10", "ts-node": "10.9.1", "typescript": "4.5.2" }, "dependencies": { "class-transformer": "^0.5.1", "class-validator": "^0.14.1", "express": "^4.19.2", "pg": "^8.4.0", "reflect-metadata": "^0.1.13", "typeorm": "0.3.20" }, "scripts": { "start": "ts-node src/main.ts", "typeorm": "typeorm-ts-node-commonjs" } }
错误日志
[+] Running 3/3 ✔ Network myproject_default Created 0.0s ✔ Container myproject-db-1 Created 0.0s ✔ Container myproject-server-1 Created 0.0s Attaching to db-1, server-1 db-1 | db-1 | PostgreSQL Database directory appears to contain a database; Skipping initialization db-1 | db-1 | 2024-03-30 00:39:29.465 UTC [1] LOG: starting PostgreSQL 16.2 (Debian 16.2-1.pgdg120+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit db-1 | 2024-03-30 00:39:29.465 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 db-1 | 2024-03-30 00:39:29.465 UTC [1] LOG: listening on IPv6 address "::", port 5432 db-1 | 2024-03-30 00:39:29.476 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" db-1 | 2024-03-30 00:39:29.489 UTC [29] LOG: database system was shut down at 2024-03-30 00:39:17 UTC db-1 | 2024-03-30 00:39:29.497 UTC [1] LOG: database system is ready to accept connections server-1 | server-1 | > TaskManager@0.0.1 start server-1 | > ts-node src/main.ts server-1 | server-1 | Error: connect ECONNREFUSED 127.0.0.1:5432 server-1 | at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1605:16) { server-1 | errno: -111, server-1 | code: 'ECONNREFUSED', server-1 | syscall: 'connect', server-1 | address: '127.0.0.1', server-1 | port: 5432 server-1 | } server-1 exited with code 0
解决方案
1. 确保数据库完全就绪后启动后端
depends_on仅保证容器启动顺序,不确保PostgreSQL服务已完全可用。需要给数据库添加健康检查,让后端等待数据库就绪后再启动:
修改docker-compose.yml的db服务,添加健康检查:
db: image: postgres volumes: - ./data/db:/var/lib/postgresql/data environment: - POSTGRES_DB=taskmanagerdb - POSTGRES_USER=admin - POSTGRES_PASSWORD=mysecretpassword ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U admin -d taskmanagerdb"] interval: 5s timeout: 5s retries: 5
同时修改server服务的depends_on,依赖数据库的健康检查通过:
server: build: . ports: - "3000:3000" depends_on: db: condition: service_healthy environment: - PGHOST=db
2. 统一配置来源,避免覆盖
虽然data-source.ts中指定了host: "db",但可能存在环境变量或其他配置覆盖的情况。建议将TypeORM配置改为从环境变量读取,确保一致性:
修改data-source.ts:
export const AppDataSource = new DataSource({ type: "postgres", host: process.env.PGHOST || "db", port: parseInt(process.env.PGPORT || "5432"), username: process.env.PGUSER || "admin", password: process.env.PGPASSWORD || "mysecretpassword", database: process.env.PGDATABASE || "taskmanagerdb", synchronize: true, logging: false, entities: [User, Task, Category], migrations: [], subscribers: [], })
在docker-compose.yml的server服务中补充完整环境变量:
environment: - PGHOST=db - PGPORT=5432 - PGUSER=admin - PGPASSWORD=mysecretpassword - PGDATABASE=taskmanagerdb
3. 排查网络连通性
如果上述步骤无效,可进入后端容器测试与数据库服务的连通性:
# 测试ping连通性 docker exec -it myproject-server-1 ping db # 测试端口是否开放 docker exec -it myproject-server-1 nc -zv db 5432
若网络不通,检查docker-compose默认网络是否正常,或手动指定网络确保服务在同一网络下。
内容的提问来源于stack exchange,提问作者KauanRossi
相关产品推荐
相关产品推荐

