1

Searching the solution for How to search the exact cause "[TypeOrmModule] Unable to connect to the database." error in NestJS + TypeORM + Docker case?, I has been recommended to check ECONNREFUSED for Postgres on nodeJS with dockers topics. First that I noticed is the production setup of Posgres/TypeORM is different from local development one by not only values but also by adding of extra properties.

In my case, below setup works fine locally:

import { Module as NestJS_Module } from "@nestjs/common";
import { TypeOrmModule, TypeOrmModule as TypeORM_Module } from "@nestjs/typeorm";
import type { TypeOrmModuleOptions } from "@nestjs/typeorm";
import ConfigurationRepresentative from "./Configuration/ConfigurationRepresentative";

@NestJS_Module({
  imports: [
    TypeORM_Module.forRootAsync({
      useFactory: (): TypeOrmModuleOptions => ({
      type: "postgres",
      host: "localhost",
      port: 5432,
      username: "postgres",
      password: "pass1234"
        autoLoadEntities: true,
        synchronize: ConfigurationRepresentative.isLocalExecutionEnvironment
      })
    }),
  ]
})
export default class NestJS_ApplicationRootModule {}

herewith, the docker-compose.yml for the local development case is:

version: "3"

services:

  Database:

    image: postgres
    container_name: LocalDatabase
    restart: always
    ports:
      - "5432:5432"

    volumes:
      - DataBaseData:/var/lib/postgresql/data

volumes:
  DataBaseData:
    driver: local

The preset from ECONNREFUSED for Postgres on nodeJS with dockers is

web:
  image: node
  command: npm start
  ports:
    - "8000:4242"
  links:
    - db
  working_dir: /src
  environment:
    SEQ_DB: mydatabase
    SEQ_USER: username
    SEQ_PW: pgpassword
    PORT: 4242
    DATABASE_URL: postgres://username:pgpassword@127.0.0.1:5432/mydatabase
  volumes:
    - ./:/src
db:
  image: postgres
  ports:
  - "5432:5432"
  environment:
    POSTGRES_USER: username
    POSTGRES_PASSWORD: pgpassword

Is there something that we can safely remove? I suppose:

  • The mydatabase already has been defined in SEQ_DB. Why we need to duplicate it in DATABASE_URL?
  • Same for SEQ_USER and SEQ_PW.
  • Why we need to explicitly define the DATABASE_URL? Could not it be computed automatically?

Currently, my docker-compose.yaml for the production is:

version: "3"

services:

  node_js:

    container_name: FrontServer
    build: .
    ports: [ "3000:3000" ]
    depends_on: [ "database" ]

  database:

    container_name: Database

    image: postgres
    ports: [ "5432:5432" ]

    environment:
      - POSTGRES_PASSWORD=pass1234
      # - POSTGRES_PASSWORD=${DATABASE_PASSWORD} It should work too but first I need to connect

    volumes:
      - Database:/data/example.com

volumes:
  Database: {}

Also, how TypeORM_Module.forRootAsync will change? I suppose, it will be different host (db instead of localhost?), of course, different password and some extra options.

Takeshi Tokugawa YD
  • 670
  • 5
  • 40
  • 124

1 Answers1

1

Is there something that we can safely remove? I suppose: The mydatabase already has been defined in SEQ_DB. Why we need to duplicate it in DATABASE_URL? Same for SEQ_USER and SEQ_PW. Why we need to explicitly define the DATABASE_URL? Could not it be computed automatically?

As you copied this from an example, I think it shows you both options you can use, depending on your code. As both are valid options but normally are not used combined. Some people prefer to use a database URL to connect to the database, some prefer single variables. You can decide, though you also should use the same method in development.

Some companies only consider the password a secret, some also the username and some even the hostname. The more parts are seen as a secret, the more since it makes to use the database URL, as then you simply make the whole thing a single secret instead of 3 secrets.

Also on bigger projects, that have for example 50 configuration variables, you might want to consider reducing them and combine the connection to the database.

Also, how TypeORM_Module.forRootAsync will change? I suppose, it will be different host (db instead of localhost?), of course, different password and some extra options.

Almost right. In your production docker-compose.yaml you are calling the service database not db. Therefore, you need to change localhost with database

  • 1
    Thank you for the answer! In my case, `SEQ_DB` ,`SEQ_USER`, `DATABASE_URL` was not required. Also, your last directions ("Therefor, you need to change...") saved my day. – Takeshi Tokugawa YD Nov 26 '22 at 12:35