Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker - SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:3306

I'm trying to get my nodejs application up and running using a docker container. I have no clue what might be wrong. The credentials seems to be passed correctly when I debug the credentials with the console. Also firing up sequel pro and connecting directly with the same username and password seems to work. When node starts in the container I get the error message:

SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:3306

The application itself is loading correctly on port 3000, however no data is retrieved from the database. If have also tried adding the environment variables directly to the docker compose file, but this also doesn't seem to work.

My project code is hosted over here: https://github.com/pietheinstrengholt/rssmonster

The following database.js configuration is used. When I add console.log(config) the correct credentials from the .env file are displayed.

require('dotenv').load();

const Sequelize = require('sequelize');
const fs = require('fs');
const path = require('path');
const env = process.env.NODE_ENV || 'development';
const config = require(path.join(__dirname + '/../config/config.js'))[env];

if (config.use_env_variable) {
  var sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  var sequelize = new Sequelize(config.database, config.username, config.password, config);
}

module.exports = sequelize;

When I do a console.log(config) inside the database.js I get the following output:

{
username: 'rssmonster',
password: 'password',
database: 'rssmonster',
host: 'localhost',
dialect: 'mysql'
}

Following .env:

DB_HOSTNAME=localhost
DB_PORT=3306
DB_DATABASE=rssmonster
DB_USERNAME=rssmonster
DB_PASSWORD=password

And the following docker-compose.yml:

version: '2.3'
services:

  app:
    depends_on:
      mysql:
        condition: service_healthy
    build:
      context: ./
      dockerfile: app.dockerfile
    image: rssmonster/app
    ports:
      - 3000:3000
    environment:
      NODE_ENV: development
      PORT: 3000
      DB_USERNAME: rssmonster
      DB_PASSWORD: password
      DB_DATABASE: rssmonster
      DB_HOSTNAME: localhost
    working_dir: /usr/local/rssmonster/server
    env_file:
      - ./server/.env
    links:
      - mysql:mysql

  mysql:
    container_name: mysqldb
    image: mysql:5.7
    command: --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: "yes"
      MYSQL_DATABASE: "rssmonster"
      MYSQL_USER: "rssmonster"
      MYSQL_PASSWORD: "password"
    ports:
      - "3307:3306"
    volumes:
      - /var/lib/mysql
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
      timeout: 5s
      retries: 10

volumes:
  dbdata:

Error output:

{ SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:3306
app_1    |     at Promise.tap.then.catch.err (/usr/local/rssmonster/server/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:128:19)
app_1    | From previous event:
app_1    |     at ConnectionManager.connect (/usr/local/rssmonster/server/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:125:13)
app_1    |     at sequelize.runHooks.then (/usr/local/rssmonster/server/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:306:50)
app_1    | From previous event:
app_1    |     at ConnectionManager._connect (/usr/local/rssmonster/server/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:306:8)
app_1    |     at ConnectionManager.getConnection (/usr/local/rssmonster/server/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:247:46)
app_1    |     at Promise.try (/usr/local/rssmonster/server/node_modules/sequelize/lib/sequelize.js:564:34)
app_1    | From previous event:
app_1    |     at Promise.resolve.retryParameters (/usr/local/rssmonster/server/node_modules/sequelize/lib/sequelize.js:464:64)
app_1    |     at /usr/local/rssmonster/server/node_modules/retry-as-promised/index.js:60:21
app_1    |     at new Promise (<anonymous>)
like image 837
Erhnam Avatar asked Dec 31 '18 14:12

Erhnam


3 Answers

Insteaf of localhost point to mysql which is the service name (DNS) that nodejs will resolve into the MySQL container:

DB_HOSTNAME: mysql

And

 {
  ...
  host: 'mysql',
  ...
 }
like image 164
Robert Avatar answered Oct 21 '22 14:10

Robert


Inside of the container you should reference the container by the name you gave in your docker-compose.yml file.

In this case you should use

DB_HOSTNAME: mysql
like image 34
ClickThisNick Avatar answered Oct 21 '22 14:10

ClickThisNick


After searching and digging up through several googling attempt, the culprit of the problem soon appear. In this context, the database server is not in the same machine. In other words, the MySQL Database Server address is not localhost. So, how can the above MySQL database configuration by default is pointing to localhost address. Well, it seems that if there is no further definition of the host address, it will connect to the localhost address by default. Read the article for further reference about sequelize syntax pattern in this link.

So, in order to solve the problem, just modify the file with the right configuration database. The following is the correction of the configuration database :

const sequelize = require("sequelize")

const db = new sequelize("db_master","db_user","password", {
        host : "10.0.2.2",
        dialect: "mysql"
});

db.sync({});

module.exports = db;

Actually, the NodeJS application is running in a virtual server. It is a guest machine run in a VirtualBox application. On the other hand, MySQL Database server exist outside the guest machine. It is available in the host machine where the VirtualBox application is running. The host machine IP address is 10.0.2.2. So, in order to connect to MySQL Database Server in the host machine, the IP address of the host is 10.0.2.2.

like image 33
Manoj Gupta Avatar answered Oct 21 '22 13:10

Manoj Gupta