11

I am trying to setup some containers for my NestJS + TypeORM + MySQL environment by using Docker Compose in a Windows 10 host, but I am getting an ECONNREFUSED error:

connect ECONNREFUSED 127.0.0.1:3306 +2ms
backend_1  | Error: connect ECONNREFUSED 127.0.0.1:3306
backend_1  |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1145:16)
backend_1  |     --------------------
backend_1  |     at Protocol._enqueue (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:144:48)
backend_1  |     at Protocol.handshake (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:51:23)        
backend_1  |     at PoolConnection.connect (/usr/src/app/node_modules/mysql/lib/Connection.js:116:18)
backend_1  |     at Pool.getConnection (/usr/src/app/node_modules/mysql/lib/Pool.js:48:16)
backend_1  |     at /usr/src/app/node_modules/typeorm/driver/mysql/MysqlDriver.js:793:18
backend_1  |     at new Promise (<anonymous>)
backend_1  |     at MysqlDriver.createPool (/usr/src/app/node_modules/typeorm/driver/mysql/MysqlDriver.js:790:16)
backend_1  |     at MysqlDriver.<anonymous> (/usr/src/app/node_modules/typeorm/driver/mysql/MysqlDriver.js:278:51)
backend_1  |     at step (/usr/src/app/node_modules/typeorm/node_modules/tslib/tslib.js:141:27)
backend_1  |     at Object.next (/usr/src/app/node_modules/typeorm/node_modules/tslib/tslib.js:122:57)

I have created the following Dockerfile to configure the NestJS API container:

FROM node:12-alpine
WORKDIR /usr/src/app

COPY package.json .
RUN npm install

EXPOSE 3000

#CMD ["npm", "start"]

CMD /wait-for-it.sh db:3306 -- npm start

COPY . .

And then I reference this from Docker Compose with the following docker-compose.yml:

version: "3.8"

networks:
  app-tier:
    driver: bridge

services:
  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    expose:
      - "3306"
    ports:
      - "3306:3306"    
    networks:
      - app-tier      
    environment:
      MYSQL_DATABASE: school
      MYSQL_ALLOW_EMPTY_PASSWORD: ok
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: dbuser
      MYSQL_PASSWORD: dbuser
      MYSQL_ROOT_HOST: '%'
  backend:
    depends_on:
      - db
    build: .
    ports:
      - "3000:3000"
    networks:
      - app-tier      

Finally, I set the TypeORM configuration to match with the Docker Compose file:

export const DB_CONFIG: TypeOrmModuleOptions = {
    type: 'mysql',
    host: 'db',
    port: 3306,
    username: 'dbuser',
    password: 'dbuser',
    database: 'school',
    entities: [], // We specify the entities in the App Module.
    synchronize: true,
};

I am kind of new to Docker Compose, but I have tried many things like changing the output port to 3307, setting an explicit network... and the port 3306 is free in my host OS when I run it. Any help?

Edit 1

I have included MYSQL_ROOT_HOST and wait-for-it.sh as suggested, but still no results.

1 Answers1

14

I think your db is taking more time to start and your app is starting before the db, try something like this for your docker-compose.yml file:

version: "3.8"

networks:
  app-tier:
    driver: bridge

services:
  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    expose:
      - "3306"
    ports:
      - "3306:3306"    
    networks:
      - app-tier      
    environment:
      MYSQL_DATABASE: school
      MYSQL_ALLOW_EMPTY_PASSWORD: ok
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: dbuser
      MYSQL_PASSWORD: dbuser
      MYSQL_ROOT_HOST: '%'
  backend:
    depends_on:
      - db
    build: .
    command: bash -c 'while !</dev/tcp/db/3306; do sleep 1; done; npm start'
    ports:
      - "3000:3000"
    networks:
      - app-tier   
WMRamadan
  • 974
  • 1
  • 11
  • 25