Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker Compose cannot connect to database

I'm using nestjs for my backend and using typeorm as ORM. I tried to define my database and my application in an docker-compose file.

If I'm running my database as a container and my application from my local machine it works well. My program connects and creates the tables etc.

But if I try to connect the database from within my container or to start the container with docker-compose up it fails.

Always get an ECONNREFUSED Error.

Where is my mistake ?

docker-compose.yml

version: '3.1'
volumes:
 dbdata:

services:
  db:
    image: postgres:10
    volumes:
      - ./dbData/:/var/lib/postgresql/data
    restart: always
    environment:
      - POSTGRES_PASSWORD=${TYPEORM_PASSWORD}
      - POSTGRES_USER=${TYPEORM_USERNAME}
      - POSTGRES_DB=${TYPEORM_DATABASE}
    ports:
      - ${TYPEORM_PORT}:5432

  backend:
    build: .
    ports:
      - "3001:3000"
    command: npm run start
    volumes:
      - .:/src

Dockerfile

FROM node:10.5

WORKDIR /home

# Bundle app source
COPY . /home

# Install app dependencies
#RUN npm install -g nodemon
# If you are building your code for production
# RUN npm install --only=production
RUN npm i -g @nestjs/cli
RUN npm install

EXPOSE 3000

.env

# .env
HOST=localhost
PORT=3000
NODE_ENV=development
LOG_LEVEL=debug

TYPEORM_CONNECTION=postgres
TYPEORM_HOST=localhost
TYPEORM_USERNAME=postgres
TYPEORM_PASSWORD=postgres
TYPEORM_DATABASE=mariokart
TYPEORM_PORT=5432
TYPEORM_SYNCHRONIZE=true
TYPEORM_DROP_SCHEMA=true
TYPEORM_LOGGING=all
TYPEORM_ENTITIES=src/database/entity/*.ts
TYPEORM_MIGRATIONS=src/database/migrations/**/*.ts
TYPEORM_SUBSCRIBERS=src/database/subscribers/**/*.ts

I tried to use links but it don't work in the container.

like image 535
arahfahrrad Avatar asked Dec 11 '22 06:12

arahfahrrad


2 Answers

Take a look at your /etc/hosts inside the backend container. You will see

192.0.18.1    dir_db_1

or something like that. The IP will be different and dir will represent the dir you're in. Therefore, you must change TYPEORM_HOST=localhost to TYPEORM_HOST=dir_db_1.

Although, I suggest you set static names to your containers.

services:
  db:
    container_name: project_db
    ...
  backend:
    container_name: project_backend

In this case you can always be sure, that your container will have a static name and you can set TYPEORM_HOST=project_db and never worry about the name ever again.

like image 125
Alex Karshin Avatar answered Dec 31 '22 08:12

Alex Karshin


You can create a network and share among two services.

Create network for db and backend services:

networks:
  common-net: {}

and add the network to these two services. So your .yml file would like below after edit:

version: '3.1'
volumes:
 dbdata:

services:
  db:
    image: postgres:10
    volumes:
      - ./dbData/:/var/lib/postgresql/data
    restart: always
    environment:
      - POSTGRES_PASSWORD=${TYPEORM_PASSWORD}
      - POSTGRES_USER=${TYPEORM_USERNAME}
      - POSTGRES_DB=${TYPEORM_DATABASE}
    ports:
      - ${TYPEORM_PORT}:5432
    networks:
      - common-net

  backend:
    build: .
    ports:
      - "3001:3000"
    command: npm run start
    volumes:
      - .:/src
    networks:
      - common-net


networks:
  common-net: {}
Note1: After this change, there is no need to expose the Postgres port externally unless you have a reason for it. You can remove that section.
Note2: TYPEORM_HOST should be renamed to db. Docker would resolve the IP address of db service by itself.
like image 24
Ali Nowrouzi Avatar answered Dec 31 '22 08:12

Ali Nowrouzi