Search code examples
mysqldockernestjstypeorm

Unable to connect to MySQL database in NestJS using docker


I am trying to connect my NestJS project with MySQL database using TypeORM using docker but it isn't working. However, when I run my NestJS app without docker container it connects to my local MySQL database correctly. Here is my project structure

enter image description here

Here is my docker-compose.yml file

version: '3.8'

services:
  mysqldb:
    image: mysql:latest
    restart: always
    cap_add:
      - SYS_NICE
    env_file: ./.env
    environment:
      - MYSQL_ROOT_PASSWORD=$MYSQLDB_ROOT_PASSWORD
      - MYSQL_DATABASE=$MYSQLDB_DATABASE
    ports:
      - $MYSQLDB_LOCAL_PORT:$MYSQLDB_DOCKER_PORT
    volumes:     
      - db:/var/lib/mysql
      - ./db/init_database.sql:/docker-entrypoint-initdb.d/init_database.sql
    networks:
      - backend  

  demo-api:
    depends_on:
      - mysqldb
    build: ./demo-api
    restart: unless-stopped
    env_file: ./.env
    ports:
      - $NODE_LOCAL_PORT:$NODE_DOCKER_PORT
    environment:
      - DB_HOST=mysqldb
      - DB_USER=$MYSQLDB_USER
      - DB_PASSWORD=$MYSQLDB_ROOT_PASSWORD
      - DB_NAME=$MYSQLDB_DATABASE
      - DB_PORT=$MYSQLDB_DOCKER_PORT
      - CLIENT_ORIGIN=$CLIENT_ORIGIN
    networks:
      - backend
      - frontend

  demo-ui:
    depends_on:
      - demo-api
    build:
      context: ./demo-ui
      args:
        - REACT_APP_API_BASE_URL=$CLIENT_API_BASE_URL
    ports:
      - $REACT_LOCAL_PORT:$REACT_DOCKER_PORT
    networks:
      - frontend  

volumes: 
  db:
    driver: local

networks:
  backend:
  frontend:

This is how my .env file looks in the project root folder

MYSQLDB_USER=root
MYSQLDB_ROOT_PASSWORD=123456
MYSQLDB_DATABASE=demo_db
MYSQLDB_LOCAL_PORT=3307
MYSQLDB_DOCKER_PORT=3306

NODE_LOCAL_PORT=6868
NODE_DOCKER_PORT=8080

CLIENT_ORIGIN=http://127.0.0.1:8888
CLIENT_API_BASE_URL=http://127.0.0.1:8080/api

REACT_LOCAL_PORT=8888
REACT_DOCKER_PORT=80

And this is how my .env file looks inside the demo-api folder

DB_TYPE=mysql
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=123456
DB_NAME=demo_db
DB_PORT=3306

# JWT
JWT_SECRET=<YOUR JWT SECRET>

NODE_DOCKER_PORT=8080

CLIENT_ORIGIN=http://127.0.0.1:8081

And this is how I am setting up the database connection in app.module.ts file

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module';
import { User } from './users/entities/user.entity';
import { UsersModule } from './users/users.module';

const entities = [User];

const DBModule = TypeOrmModule.forRootAsync({
  useFactory: async () => ({
    type: process.env.DB_TYPE as any,
    host: process.env.DB_HOST,
    port: parseInt(process.env.DB_PORT),
    username: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
    entities: entities,
    synchronize: true,
  }),
});

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    DBModule,
    UsersModule,
    AuthModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Am I missing or doing something wrong in my docker-compose.yml file?


Solution

  • Running docker-compose down -v and then running docker-compose up again resolved the issue for me