Home > Software design >  Nest.js TypeORM connect to local database (on docker container)
Nest.js TypeORM connect to local database (on docker container)

Time:10-31

I have local MySQL database created in docker container from following docker-compose.yml

version: '3.6'
services:
  mysql:
    environment:
      - MYSQL_DATABASE=test
      - MYSQL_ROOT_PASSWORD=changeme
      - MYSQL_USER=dbuser
      - MYSQL_PASSWORD=changeme
    command:
      - --table_definition_cache=100
      - --performance_schema=0
      - --default-authentication-plugin=mysql_native_password
      - --innodb_use_native_aio=0
    volumes:
      - ./init:/docker-entrypoint-initdb.d
    container_name: mysqldb
    image: mysql

And it's working fine - I can enter docker container, log in as root user (or dbuser) and create databases, tables, execute queries, etc. I also have Nest.js application which uses @nestjs/typeorm module to connect to database using following ormconfig.json:

{
  "type": "mysql",
  "host": "localhost",
  "port": 3306,
  "username": "dbuser",
  "password": "changeme",
  "database": "test",
  "synchronize": true,
  "entiries": ["src/**/*/entity.ts"]
}

And here is the problem - when I start application I get following error:

Error: ER_ACCESS_DENIED_ERROR: Access denied for user 'dbuser'@'172.22.0.1' (using password: YES)

It seems that all data in ormconfig.json are correct - why my application can't connect to database?

CodePudding user response:

You do not have the port bound to your localhost.

Quick and dirty solution: Add the following to your mysql service in the docker-compose.yml:

ports:
  - "3306:3306"

More complete solution Move your NestJS app into your docker-compose.yml too.

  1. Create dev.Dockerfile in your folder with something like this inside:
FROM node:16-alpine

WORKDIR /srv/app

CMD npm run start:dev

  1. Add your app to docker-compose.yml:
  api:
    build:
      context: .
      dockerfile: ./dev.Dockerfile
    volumes:
      - ./:/srv/app
    depends_on:
      - mysql
    environment:
      MYSQL_HOST: "mysql"
    ports:
      - "3000:3000"

If you go this way, your app will access MySQL instance through the Docker Compose network, without the need to bind MySQL port to your localhost. It will still give nice DX as you will have hot reloading in this setup.

I hope it helps. In case of issues, feel free to comment and I will explain/edit.

  • Related