Nodejs application cannot communicate with postgresql (docker-compose)

62 Views Asked by At

I'm trying create a docker-compose file to connect a backend created in nodejs using typeORM to manipulate and connect with a postgresql database, but always is getting error. It's working in separete containers but when I try to connect the typeORM using service name in docker-compose always returns connect ECONNREFUSED. I'm using docker compose 2.24.6 and docker 26.0.0.

nodejs 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

log error

 ✔ 
[+] 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  | > [email protected] 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

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"
   }
}

1

There are 1 best solutions below

1
datawookie On

Is your code using the defined AppDataSource? I suggest just providing a ormconfig.json file with the details. See example with full working stack below.

Assuming that your project is something like this:

├── docker-compose.yml
├── Dockerfile
├── ormconfig.json
├── package.json
├── package-lock.json
├── src
│   └── main.ts
└── tsconfig.json

docker-compose.yml

version: "3.8"

services:
  db:
    image: postgres
    environment:
      - POSTGRES_DB=taskmanagerdb
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=mysecretpassword
    ports:
      - "5432:5432"
    logging:
      driver: "none"

  server:
    container_name: server
    build: .
    ports:
      - "3000:3000"
    depends_on:
      - db
    environment:
      - PGHOST=db

Dockerfile

FROM node:alpine

COPY package*.json ./
RUN npm install

COPY . .

CMD npm start

ormconfig.json

{
    "type": "postgres",
    "host": "db",
    "port": 5432,
    "username": "admin",
    "password": "mysecretpassword",
    "database": "taskmanagerdb",
    "synchronize": true,
    "logging": false
  }

package.json

{
    "name": "TaskManager",
    "version": "0.0.1",
    "description": "Awesome project developed with TypeORM.",
    "devDependencies": {
        "@types/express": "^4.17.21",
        "@types/node": "^16.18.93",
        "ts-node": "^10.9.2",
        "typescript": "^4.9.5"
    },
    "dependencies": {
        "class-transformer": "^0.5.1",
        "class-validator": "^0.14.1",
        "express": "^4.19.2",
        "pg": "^8.11.3",
        "reflect-metadata": "^0.1.14",
        "typeorm": "^0.3.20"
    },
    "scripts": {
        "start": "ts-node src/main.ts",
        "typeorm": "typeorm-ts-node-commonjs"
    }
}

src/main.ts (A script that connects to the database and executes a simple query.)

import "reflect-metadata";
import {createConnection} from "typeorm";

console.log("Connecting to DB...");

createConnection().then(async connection => {
    console.log("Done!");

    const simpleQueryResult = await connection.query('SELECT 1;');
    console.log('Simple query result:', simpleQueryResult);

    const tablesQueryResult = await connection.query('SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname=\'public\';');
    console.log('Tables in public schema:', tablesQueryResult);

}).catch(error => console.log(error));

enter image description here