r00k13
r00k13

Reputation: 345

NestJS app build with docker can't access postgres database in the same docker network: ECONNREFUSED 127.0.0.1:5432

I want to run my app on my local machine within Docker. I don't want to optimize the size of my docker app or build it for production now.

Docker builds my backend-api app and postgres-db successfully. But I can only access the docker postgres database outside my docker e.g. with dbeaver installed on my computer. Also if I start my backend-api app WITHOUT Docker with "npm run start", my app can also access the database without any errors and can also write into the posgres db. Only when I build the backend-api with Docker and launch the app inside the Docker, I get this error. Since this only happens within Docker, I assume that something important is missing in my Dockerfile.

My docker-compose.yml:

version: '3'

services:

  backend:
    build: .
    container_name: backend-api
    command: npm run start
    restart: unless-stopped
    ports:
      - 3000:3000
    volumes:
      - .:/usr/src/backend
    networks:
      - docker-network
    depends_on:
      - database

  database:
    image: postgres:latest
    container_name: backend-db
    ports:
      - 5432:5432
    volumes:
      - postgresdb/:/var/lib/postgresql/data/
    networks:
      - docker-network
    environment:
      POSTGRES_USER: devuser
      POSTGRES_PASSWORD: devpw
      POSTGRES_DB: devdb

volumes:
  postgresdb:

networks:
  docker-network:
    driver: bridge

My Dockerfile:

FROM node:16.15.0-alpine

WORKDIR /usr/src/backend

COPY . .

RUN npm install

sudo docker-compose up --build output:

Starting backend-db ... done
Recreating backend-api ... done
Attaching to backend-db, backend-api
backend-db  | 
backend-db  | PostgreSQL Database directory appears to contain a database; Skipping initialization
backend-db  | 
backend-db  | 2022-05-03 20:35:46.065 UTC [1] LOG:  starting PostgreSQL 14.2 (Debian 14.2-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
backend-db  | 2022-05-03 20:35:46.066 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
backend-db  | 2022-05-03 20:35:46.066 UTC [1] LOG:  listening on IPv6 address "::", port 5432
backend-db  | 2022-05-03 20:35:46.067 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
backend-db  | 2022-05-03 20:35:46.071 UTC [26] LOG:  database system was shut down at 2022-05-03 20:35:02 UTC
backend-db  | 2022-05-03 20:35:46.077 UTC [1] LOG:  database system is ready to accept connections
backend-api | 
backend-api | > [email protected] start
backend-api | > nodemon
backend-api | 
backend-api | [nodemon] 2.0.15
backend-api | [nodemon] to restart at any time, enter `rs`
backend-api | [nodemon] watching path(s): src/**/*
backend-api | [nodemon] watching extensions: ts
backend-api | [nodemon] starting `IS_TS_NODE=true ts-node -r tsconfig-paths/register src/main.ts`
backend-api | [Nest] 30  - 05/03/2022, 8:35:50 PM     LOG [NestFactory] Starting Nest application...
backend-api | [Nest] 30  - 05/03/2022, 8:35:50 PM     LOG [InstanceLoader] TypeOrmModule dependencies initialized +73ms
backend-api | [Nest] 30  - 05/03/2022, 8:35:50 PM     LOG [InstanceLoader] ConfigHostModule dependencies initialized +1ms
backend-api | [Nest] 30  - 05/03/2022, 8:35:50 PM     LOG [InstanceLoader] AppModule dependencies initialized +0ms
backend-api | [Nest] 30  - 05/03/2022, 8:35:50 PM     LOG [InstanceLoader] ConfigModule dependencies initialized +1ms
backend-api | [Nest] 30  - 05/03/2022, 8:35:50 PM   ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)...
backend-api | Error: connect ECONNREFUSED 127.0.0.1:5432
backend-api |     at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1187:16)
backend-api | [Nest] 30  - 05/03/2022, 8:35:53 PM   ERROR [TypeOrmModule] Unable to connect to the database. Retrying (2)...

My ormconfig.ts:

import { ConnectionOptions } from 'typeorm';

const config: ConnectionOptions = {
  type: 'postgres',
  host: 'localhost',
  port: 5432,
  username: 'devuser',
  password: 'devpw',
  database: 'devdb',
  entities: [__dirname + '/**/*.entity{.ts,.js}'],
  synchronize: false,
  migrations: [__dirname + '/**/migrations/**/*{.ts,.js}'],
  cli: {
    migrationsDir: 'src/migrations',
  },
};

export default config;

Please let me know what other information you would like me to provide. I'm new to the Docker world.

Upvotes: 1

Views: 2269

Answers (2)

Anis
Anis

Reputation: 1220

Ran into the same issue and this docker-compose.yml setup worked for me

version: "3.8"
services:
  database:
    container_name: db
    image: postgres:14.2
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_HOST_AUTH_METHOD
  backend:
    container_name: api
    build:
      dockerfile: Dockerfile
      context: .
    restart: on-failure
    depends_on:
      - database
    ports:
      - "3000:3000"
    environment:
      - DATABASE_HOST=database
      - DATABASE_PORT=5432
      - DATABASE_USER=postgres
      - DATABASE_PASSWORD
      - DATABASE_NAME
      - DATABASE_SYNCHRONIZE
      - NODE_ENV

Following were two main notable changes

  1. changed the host to database so the docker network will route the request properly to the database service as defined in your docker-compose.yml file.
  2. added a user postgres as default PostgreSQL user

Upvotes: 2

Jay McDoniel
Jay McDoniel

Reputation: 70161

When you run a docker container localhost results in the container's localhost, not your machine's, so it's not the right host to use. As you're using docker-compose, a docker network is automatically created using the service's names as hosts. So instead of using localhost for you database host, you can use database as the host, and now the docker network will route the request properly to the database service as defined in your docker-compose.yml file

Upvotes: 3

Related Questions