Backend application container don't may to connect to db in container

I know, here a lot of similar question and I read a lot of that, but I still can’t resolve that issue.

So I have traditional docker-compose config with: posgresql, pgAdmin, nest.js app.
I run all services in docker compose, under docker network.

Db and pgAdmin is successful works, I may to connect from pgAdmin to postgres using container name ‘db’.
But when I try to connect to my db from my nest application by TypeOrm, I was take that error:

Error: getaddrinfo ENOTFOUND db at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:109:26)

When I start backend outside docker and connect by postgres container ip, all connected,
but in docker, container name / networkName / container ip not working, only one connection was without that error is with host:host.docker.internal , but then was ssl connection error, I was added url to connect pg 'postgresql://postgres:password@host.docker.internal:5435/postgres' but then was again same connection error.

docker-compose.yml

version: '3.5'

services:
  db:
    image: postgres
    env_file:
      - development.env
    environment:
      PGDATA: /data/postgres
    volumes:
      - db:/data/postgres
      - ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh
    ports:
      - "5432:5432"
    networks:
      - postgresNet
    restart: unless-stopped

  pgAdmin:
    image: dpage/pgadmin4
    restart: unless-stopped
    env_file:
      - development.env
    volumes:
      - ./pgadmin/servers.json:/pgadmin4/servers.json
      - ./pgadmin/storage:/var/lib/pgadmin/storage
    ports:
      - "5050:80"
    networks:
      - postgresNet
    command: ["/bin/sh", "-c", "python /pgadmin4/setup.py --load-servers /pgadmin4/servers.json --user ${PGADMIN_DEFAULT_EMAIL} --password ${PGADMIN_DEFAULT_PASSWORD}"]

  backend:
    build:
      context: .
      args:
        DATABASE_URL: 'postgresql://postgres:password@db:5435/postgres'
        POSTGRES_PORT: 5432
        POSTGRES_HOST: 'db'
        POSTGRES_USER: 'postgres'
        POSTGRES_PASSWORD: 'password'
        POSTGRES_DB: 'postgres'
    ports:
      - "3000:3000"
    depends_on:
      - db
    networks:
      - postgresNet

networks:
  postgresNet:
    driver: bridge

volumes:
  db:
  pgadmin:

OrmConfig.ts


const configOrm: DataSourceOptions = {
  type: 'postgres',
  host: 'db',
  port: 5432,
  username: 'postgres',
  password: 'password',
  database: 'postgres',
  logging: true,
  synchronize: false,
  entities: [`${__dirname}/**/*.entity.{ts,js}`],
  migrations: [getMigrationDirectory()],
  subscribers: ['dist/subscriber/**/*.{ts,js}'],
  ssl: (isProd || isStage) && {
    rejectUnauthorized: false,
  },
};

Please share the output of the following commands

docker version
docker info

We will have to move the topic to another category as “Community” is asking “about” the community and based on your question I guess you are using Docker Desktop.

DockerFile

#####################
## PREPARE BUILDER ##
#####################
FROM node:16 as builder

ENV NPM_CONFIG_LOGLEVEL warn
ARG POSTGRES_PORT
ARG POSTGRES_HOST
ARG POSTGRES_USER
ARG POSTGRES_PASSWORD
ARG POSTGRES_DB
ARG MAIN_CHAT_ID
ARG MODERATION_CHAT_ID
ARG BOT_TOKEN
ARG JWT_SECRET_KEY
ARG JWT_REFRESH_TOKEN_SECRET
ARG EXPIRES_IN
ARG CLIENT_URL
ARG BASE_URL
ENV POSTGRES_USER: $POSTGRES_USER
ENV POSTGRES_PASSWORD: $POSTGRES_PASSWORD
ENV POSTGRES_DB: $POSTGRES_DB
ENV MAIN_CHAT_ID: $MAIN_CHAT_ID
ENV MODERATION_CHAT_ID: $MODERATION_CHAT_ID
ENV BOT_TOKEN: $BOT_TOKEN
ENV JWT_SECRET_KEY: $JWT_SECRET_KEY
ENV JWT_REFRESH_TOKEN_SECRET: $JWT_REFRESH_TOKEN_SECRET
ENV EXPIRES_IN: $EXPIRES_IN
ENV CLIENT_URL: $CLIENT_URL
ENV BASE_URL: $BASE_URL


RUN echo $JWT_SECRET_KEY

COPY package.json yarn.lock /tmp/

RUN cd /tmp && yarn
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/

# Install app dependencies
RUN yarn install

WORKDIR /opt/app
COPY . .

ENV NODE_ENV production
RUN yarn build
RUN rm -rf node_modules/
RUN yarn add ts-node typeorm @nestjs/swagger

####################
## PREPARE RUNNER ##
####################
FROM node:16 as runner
ENV NODE_ENV production
ENV NPM_CONFIG_LOGLEVEL warn
ARG POSTGRES_PORT
ARG DATABASE_URL
ARG POSTGRES_HOST
ARG POSTGRES_USER
ARG POSTGRES_PASSWORD
ARG POSTGRES_DB
ARG MAIN_CHAT_ID
ARG MODERATION_CHAT_ID
ARG BOT_TOKEN
ARG JWT_SECRET_KEY
ARG JWT_REFRESH_TOKEN_SECRET
ARG EXPIRES_IN
ARG CLIENT_URL
ARG BASE_URL
ENV POSTGRES_DB: $POSTGRES_DB
ENV POSTGRES_HOST: $POSTGRES_HOST
ENV POSTGRES_PORT: $POSTGRES_PORT
ENV POSTGRES_USER: $POSTGRES_USER
ENV POSTGRES_PASSWORD: $POSTGRES_PASSWORD
ENV DATABASE_URL: $DATABASE_URL
ENV MAIN_CHAT_ID: $MAIN_CHAT_ID
ENV MODERATION_CHAT_ID: $MODERATION_CHAT_ID
ENV BOT_TOKEN: $BOT_TOKEN
ENV JWT_SECRET_KEY: $JWT_SECRET_KEY
ENV JWT_REFRESH_TOKEN_SECRET: $JWT_REFRESH_TOKEN_SECRET
ENV EXPIRES_IN: $EXPIRES_IN
ENV CLIENT_URL: $CLIENT_URL
ENV BASE_URL: $BASE_URL


RUN echo $JWT_SECRET_KEY


RUN mkdir -p /opt/app
WORKDIR /opt/app

COPY --from=builder /opt/app/dist /opt/app/dist
COPY --from=builder /opt/app/node_modules /opt/app/node_modules
COPY --from=builder /opt/app/package.json /opt/app/package.json
COPY --from=builder /opt/app/tsconfig.json /opt/app/tsconfig.json
COPY --from=builder /opt/app/migrations /opt/app/src/migrations
COPY --from=builder /opt/app/src/ormconfig.ts /opt/app/src/ormconfig.ts

CMD ["yarn", "run", "start:prod"]

Docker version.

Docker version 20.10.23, build 7155243
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc., v0.10.3)
  compose: Docker Compose (Docker Inc., v2.15.1)
  dev: Docker Dev Environments (Docker Inc., v0.1.0)
  extension: Manages Docker extensions (Docker Inc., v0.2.18)
  sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc., 0.6.0)
  scan: Docker Scan (Docker Inc., v0.25.0)
  scout: Command line tool for Docker Scout (Docker Inc., v0.6.0)

Docker info

Server:
 Containers: 3
  Running: 0
  Paused: 0
  Stopped: 3
 Images: 3
 Server Version: 20.10.23
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 2456e983eb9e37e47538f59ea18f2043c9a73640
 runc version: v1.1.4-0-g5fd4c4d
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
  cgroupns
 Kernel Version: 5.15.49-linuxkit
 Operating System: Docker Desktop
 OSType: linux
 Architecture: aarch64
 CPUs: 5
 Total Memory: 7.765GiB
 Name: docker-desktop
 ID: 32Q2:RGLT:MTLO:J2VD:OU4X:6ZSA:GMJS:YGMK:EU2K:CDLZ:NVMT:GNXR
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 HTTP Proxy: http.docker.internal:3128
 HTTPS Proxy: http.docker.internal:3128
 No Proxy: hubproxy.docker.internal
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  hubproxy.docker.internal:5000
  127.0.0.0/8
 Live Restore Enabled: false

It was not the output of docker version only the client part of the docker info from which I couldn’t tell if you where you are using Docker Desktop, but since Docker Desktop doesn’t support arm architecture on Windows and it is just experimental on Lunux, I ssumed thaty ou are using Docker Desktop for Mac.

I probably miss something because the compose file looks good and you are using the service name of the database to access it on the postgresNet network.

Please, show the output of the following command:

docker compose exec backend cat /etc/resolv.conf

hello @serjo96 ,

this might be a problem with your host network’s DNS

you see this post

Unless I missed something, it is a domain name resolution between two containers. On user defined Docker networks like networks created by Docker Compose you can use the service name or container name as a domain name to access another container’s port in the same network. That is not handled by the host itself so in this case I don’t think it is related to that especially not in case of Docker Desktop where the host network for Docker is the network of the virtual machine not the host of the Mac. But feell free to explain why I could be wrong :slight_smile:

Here is output of that cat command

docker compose exec backend cat /etc/resolv.conf
WARN[0000] The "POSTGRES_DB" variable is not set. Defaulting to a blank string. 
WARN[0000] The "POSTGRES_PASSWORD" variable is not set. Defaulting to a blank string. 
WARN[0000] The "POSTGRES_USER" variable is not set. Defaulting to a blank string. 
nameserver 127.0.0.11
options ndots:0

In running container, I see all my passed env

In prod running, I also connecting from by backend to db, with that options

url:. "postgresql://postgres:password@db:5435/postgres",
ssl: true

Try to update Docker Desktop, I don’t have a better idea now. Your compose version is 2.15.1 and my current compose version on Mac i 2.17.2. Although you haven’t shared the output of docker version so I can’t tell which version of Docker Desktop you have, the compose version is not up to date so it is safe to say that you are using an older Docker Desktop too.

Mac docker

docker version
Client:
 Cloud integration: v1.0.31
 Version:           20.10.23
 API version:       1.41
 Go version:        go1.18.10
 Git commit:        7155243
 Built:             Thu Jan 19 17:35:19 2023
 OS/Arch:           darwin/arm64
 Context:           desktop-linux
 Experimental:      true

Server: Docker Desktop 4.17.0 (99724)
 Engine:
  Version:          20.10.23
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.18.10
  Git commit:       6051f14
  Built:            Thu Jan 19 17:31:28 2023
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          1.6.18
  GitCommit:        2456e983eb9e37e47538f59ea18f2043c9a73640
 runc:
  Version:          1.1.4
  GitCommit:        v1.1.4-0-g5fd4c4d
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Its also same problem on my ubuntu server

Ubuntu docker

sudo docker version
Client: Docker Engine - Community
 Version:           23.0.4
 API version:       1.42
 Go version:        go1.19.8
 Git commit:        f480fb1
 Built:             Fri Apr 14 10:32:23 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          23.0.4
  API version:      1.42 (minimum version 1.12)
  Go version:       go1.19.8
  Git commit:       cbce331
  Built:            Fri Apr 14 10:32:23 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.20
  GitCommit:        2806fc1057397dbaeefbea0e4e17bddfbd388f38
 runc:
  Version:          1.1.5
  GitCommit:        v1.1.5-0-gf19387a
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Were you able to solve the issue? I checked our first post again and noticed node:dns and I thought, what if your nodejs app has its own DNS server and doesn’t use the internal DNS? If this is the case, the container will not know about “db” as domain name

Hello again, thanks for reply, nope, unfortunately still don’t fix it, I was found hot fix with that config:
Here I also remove the docker network

version: '3.5'

services:
  db:
    image: postgres
    env_file:
      - development.env
    environment:
      PGDATA: /data/postgres
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}" ]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s
    volumes:
      - db:/data/postgres
      - ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh
    ports:
      - "5432:5432"
    restart: unless-stopped

  pgAdmin:
    image: dpage/pgadmin4
    restart: unless-stopped
    env_file:
      - development.env
    volumes:
      - ./pgadmin/servers.json:/pgadmin4/servers.json
      - ./pgadmin/storage:/var/lib/pgadmin/storage
    ports:
      - "5050:80"

    command: ["/bin/sh", "-c", "python /pgadmin4/setup.py --load-servers /pgadmin4/servers.json --user ${PGADMIN_DEFAULT_EMAIL} --password ${PGADMIN_DEFAULT_PASSWORD}"]

  backend:
    env_file:
      - development.env
    build:
      context: .
    ports:
      - "3000:3000"
    depends_on:
      - db

volumes:
  db:
  pgadmin:

And env

DATABASE_URL=postgresql://postgres:password@db:5435/postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
POSTGRES_DB=postgres
POSTGRES_HOST=db
POSTGRES_PORT=5432
PORT=3000

PGADMIN_DEFAULT_EMAIL=admin@example.com
PGADMIN_DEFAULT_PASSWORD=qwerty123

at OrmConfig also have problem with connect for prod form url, so I removed connect from url.

if(isProd) {
configOrm = {...configOrm, ...{
    url: config.DATABASE_URL,
    ssl:true
  }}
} else {
  configOrm = {...configOrm, ... {
      host: config.POSTGRES_HOST,
      port: +config.POSTGRES_PORT,
      username: config.POSTGRES_USER,
      password: config.POSTGRES_PASSWORD,
      database: config.POSTGRES_DB,
    }}

And its works with that hot fix, but its just hot fix…
Main problem for prod its connect with that url postgresql://postgres:password@db:5435/postgres

I am not sure I understand everything correctly. What happens when you remove only the postgresNet definitiót and references without changing anything else?

In your case you wouldn’t even need that network in this compose project, because Docker Compose creates acustom network by default. If name resolution works with the default, but not with postgresNet, then the issue is somehow with postgresNet. If you also need to change your source code even when using the default compose project network, then the issue is in your source code and I am not sure we can hepl you with that.

can your share the output of the followinf command which shows the definition of postgresNet?

docker network inspect <NETWORK_NAME>

where <NETWORK_NAME> should be the actual name of the postgresNet which hs a prefix on the host. If you are not sure what that is, list the networks first:

docker network ls