'NodeJS Cannot Connect to Postgres at Dockerized Environment

I am trying to run a NodeJS application on Docker. However I get that error:

could not connect to postgres: Error: connect ECONNREFUSED

When I debug the problem I can see that my environment file is considered from the application and I can access the application endpoints until it tries to connect database.

What can be the reason?

This is my docker-compose.yml file:

version: "3.8"

services:
  postgres:
    image:postgres:12.4
    restart: always
    environment:
      POSTGRES_USER: workflow
      POSTGRES_DB: workflow
      POSTGRES_PASSWORD: pass
    ports:
      - "5429:5432"
    expose:
      - 5429
    networks:
      - db

  workflow:
    image:workflow:0.1.0-SNAPSHOT
    environment:
      NODE_ENV: prod
    env_file:
      - ./.env.prod
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    ports:
      - "3000:3000"
    networks:
      - db
    depends_on:
      - postgres

networks:
  db:

volumes:
  db-data:

This is my Dockerfile:

FROM node:16.14.2

WORKDIR /app

COPY ["package.json", "package-lock.json*", "./"]

RUN npm ci --only=production && npm cache clean --force
COPY . .

CMD [ "npm", "run", "start"]

This is .env.prod file:

PORT=3000
DATABASE_URL=postgresql://workflow:pass@postgres:5429/workflow

Here is the related script from package.json:

"scripts": {
  "start": "npm run migrate up && node src/app.js"
}

This is error output:

workflow_1  | Error: connect ECONNREFUSED 172.21.0.2:5429
workflow_1  |     at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1157:16) {
workflow_1  |   errno: -111,
workflow_1  |   code: 'ECONNREFUSED',
workflow_1  |   syscall: 'connect',
workflow_1  |   address: '172.21.0.2',
workflow_1  |   port: 5429
workflow_1  | }

This is from docker ps command:

CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS                              NAMES
c8971741b19d  postgres:12.4   "docker-entrypoint.s…"   50 seconds ago   Up 49 seconds   5429/tcp, 0.0.0.0:5429->5432/tcp   workflow_postgres_1


Solution 1:[1]

Based on the official Dockerfile of the postgres:12.4 database it exposes default port 5432. So unless you changed that port with the pg configuration your application needs to connect to port 5432, not the 5429.

Also based on your

ports:
    - "5429:5432"

section of the docker compose. If you go to the official documentation it is

ports (HOST:CONTAINER)

for the syntax. So you are technically mapping port 5429 to the "outside/host" port. Meanwhile all the internal docker traffic still goes to the port 5432.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 matic1123