Attempting to connect database from within the microservice, failing to the connect the database
Error: connect ECONNREFUSED 172.18.0.2:3306
service/index.js
var http = require('http');
//create a server object:
http.createServer(function (req, res) {
res.write('Hello World!'); //write a response to the client
res.end(); //end the response
}).listen(8080); //the server object listens on port 8080
console.log("Listening at 8080");
var mysql = require('mysql');
var con = mysql.createConnection({
host: "database",
user: "root",
password: "password"
});
con.connect(function(err) {
if (err) throw err;
console.log("Database Connected!");
});
docker-compose.yml
version: '3'
services:
database:
build:
./database
ports:
- "6603:3306"
image: "test-mysql"
container_name: "test-mysql"
service:
build:
./service
ports:
- "8080:8080"
depends_on:
- database
image: "test-nodejs"
container_name: "test-nodejs"
restart: on-failure
I've attempted connecting to database with different settings.
1) Without port
var con = mysql.createConnection({
host: "database",
user: "root",
password: "password"
});
2) specified port 3306
var con = mysql.createConnection({
host: "database",
user: "root",
password: "password"
port: 3306
});
3) specified port 6603
var con = mysql.createConnection({
host: "database",
user: "root",
password: "password",
port: 6603
});
database/Dockerfile
FROM mysql
ENV MYSQL_DATABASE=test
ENV MYSQL_ROOT_PASSWORD=password
EXPOSE 6603:3306
COPY ./schema.sql /docker-entrypoint-initdb.d/
Basically how my node.js microservice can discover the database service?
Edit
I suspected that database wasn't ready by the time nodejs kicks in, so I added some delay before connecting to database and error changed
Updated Code
setTimeout(function(){
var mysql = require('mysql');
var con = mysql.createConnection({
host: "database",
user: "root",
password: "password"
});
con.connect(function(err) {
if (err) throw err;
console.log("Database Connected!");
});
}, 20 * 1000);
output
Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
Probably you are using a version of MySQL that doesnt support the login you are trying. Try with mysql v5.7:
docker run -d -p 6603:3306 --name mysql-container -e MYSQL_ROOT_PASSWORD=password mysql:5.7
You miss order:
First connect to database, then listen the port.
var http = require('http');
var mysql = require('mysql');
var con = mysql.createConnection({
host: "database",
user: "root",
password: "password"
} );
con.connect(function(err) {
if (err) throw err;
console.log("Database Connected!");
});
//create a server object:
http.createServer(function (req, res) {
res.write('Hello World!'); //write a response to the client
res.end(); //end the response
}).listen(8080); //the server object listens on port 8080
console.log("Listening at 8080");
the database port does not get translated as it's within the container. just use 3306 in your app
Related
This question already has answers here:
ECONNREFUSED for Postgres on nodeJS with dockers
(7 answers)
Closed 5 months ago.
i'm trying to build a web app using NodeJS (with expressJS) as backend and MySQL for the database. This is all built and used with a docker-compose.yml, and a dockerfile for nodejs.
Problem is, the server can't connect to the database, it keep giving me this error in docker-compose logs :
/usr/src/app/server.js:17
if (err) throw err
^
Error: connect ECONNREFUSED 127.0.0.1:3606
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1300:16)
--------------------
at Protocol._enqueue (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:144:48)
at Protocol.handshake (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:51:23)
at PoolConnection.connect (/usr/src/app/node_modules/mysql/lib/Connection.js:116:18)
at Pool.getConnection (/usr/src/app/node_modules/mysql/lib/Pool.js:48:16)
at startServer (/usr/src/app/server.js:16:10)
at Object.<anonymous> (/usr/src/app/server.js:28:1)
at Module._compile (node:internal/modules/cjs/loader:1119:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1173:10)
at Module.load (node:internal/modules/cjs/loader:997:32)
at Module._load (node:internal/modules/cjs/loader:838:12) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 3606,
fatal: true
}
Here is my docker-compose.yml :
services:
db:
image: mysql:latest
restart: unless-stopped
environment:
- MYSQL_DATABASE = areadb
- MYSQL_ROOT_PASSWORD = password
ports:
- 3606:3606
volumes:
- sql-db:/var/lib/mysql
networks:
- backend
server:
depends_on:
- db
build: ./server
restart: unless-stopped
environment:
- MYSQL_DATABASE = areadb
- MYSQL_USER = root
- MYSQL_PASSWORD = password
- MYSQL_HOST = db
ports:
- 8080:8080
networks:
- backend
networks:
backend:
volumes:
sql-db:
And the server.js file that is used at the start :
const express = require("express");
const mysql = require("mysql");
function startServer() {
const app = express();
const port = 8080;
const pool = mysql.createPool({
connectionLimit: 10,
host: "127.0.0.1",
user: "root",
password: "password",
database: "areadb",
port: "3606"
});
pool.getConnection(function (err, connection) {
if (err) throw err
else console.log("App successfully connected to MySQL database.");
});
app.get("/", (req, res) => {
res.send("Hello World");
});
app.listen(port, function () {
console.log("Listening on port 8080");
});
}
startServer();
Please help me understand why this error happens and how can I fix it.
Notice how the correct connection information is all present in your docker-compose.yml:
environment:
- MYSQL_DATABASE = areadb
- MYSQL_USER = root
- MYSQL_PASSWORD = password
- MYSQL_HOST = db
So it would be a shame not to use it in your server.js:
host: process.env.MYSQL_HOST,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE,
port: 3606 // might also want to make this an environment variable
An an aside, instead of port 3606 I think you mean 3306, which is the default MySQL port.
I am trying to fetch data from a MySQL table. It works perfectly when I hardcode the configuration. But when I use env variables to configure it, I get the following error:
code: 'ER_NOT_SUPPORTED_AUTH_MODE',
errno: 1251,
sqlMessage: 'Client does not support authentication protocol requested by server; consider upgrading MySQL client',
sqlState: '08004',
fatal: true
This is my .env.local file:
MYSQL_HOST: localhost
MYSQL_USER: root
MYSQL_PASSWORD:************
MYSQL_DB:***
this is my db connections code:
const mysql = require("mysql");
var db = mysql.createConnection({
host: process.env.MYSQL_HOST,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DB,
});
db.connect((err) => {
if (err) {
console.log(err);
} else {
console.log("connected to db");
}
});
module.exports = db;
The issue is resolved. I used ':' instead of '='.
I am getting an error when I run this code, it says Port should be >= 0 and < 65536 and i sent 123456. how can i make my port smaller?
const mysql = require('mysql');
require('dotenv').config();
var connection = mysql.createConnection({
port: process.env.DB_PORT,
port: process.env.DB_HOST,
port: process.env.DB_USERNAME,
port: process.env.DB_PASSWORD,
database: process.env.DB_NAME
})
connection.connect((err) =>{
if (!err){
console.log("Connected");
}
else{
console.log(err);
}
});
module.exports = connection;
I have started node-js recently and i was trying to connect my nodejs server with mysql.
The problem is i am getting an error, i really don't know why, i am using phpmyadmin.
Phpmyadmin details
user: root
host: localhost
password is not set
This is the image of my phpmyadmin database
This is the settings of my phpmyadmin console
This is the terminal where it is showing error connecting to DB
index.js
var express = require("express");
var app = express();
var mysql = require('mysql');
var port = process.env.PORT || 3000;
var connection = mysql.createConnection({
host: "localhost",
user: "root",
database: "learning",
});
connection.connect(function(err){
if(err) {
console.log('Error connecting to Db');
return;
}
console.log('Connection established');
console.log('3');
connection.end(function(err) {
console.log('Connection closed');
console.log('4');
process.exit();
});
});
app.listen(port,function(err1){
console.log("Listening on the port 3000");
});
connection to mysql from node js, you are use to mysql from node js connection
/config
/database.js
/server.js
/.env
const http = require('http');
const app = require('express')();
require('./config/database.js');
const bodyParser = require('body-parser');
const server = http.createServer(app);
server.listen(process.env.ServerPort, '0.0.0.0', () => {
logger.info(`Express server listening on port ${process.env.ServerPort}`);
});
When you run this:
node server.js
database.js file
const My = require('jm-ez-mysql');
// Init DB Connection
const connection = My.init({
host: process.env.DBHOST,
user: process.env.DBUSER,
password: process.env.DBPASSWORD,
database: process.env.DATABASE,
dateStrings: true,
charset: 'utf8mb4',
timezone: 'utc',
multipleStatements: true,
connectTimeout: 100 * 60 * 1000,
acquireTimeout: 100 * 60 * 1000,
timeout: 100 * 60 * 1000,
});
module.exports = {
connection,
};
I had changed the port from default 3306 of phpmyadmin mysql to 3308
therefore i added port: 3308 and it started working.
var connection = mysql.createConnection({
host: "localhost",
user: "root",
database: "learning",
port: 3308
});
I have two VM on Azure:
Machine A: is the server which run a Nodejs application
Machine B: is a VM which is running a mysql instance
Machine A and B are in the same VPN, either with a local address. I tested the connection from Machine A to B using ping and it works.
My problem is regarding the database connection from the nodejs app and mysql instance.
app.js
var express = require('express'),
config = require('./config/config'),
db = require('./app/models');
var app = express();
module.exports = require('./config/express')(app, config);
db.sequelize
.sync()
.then(function () {
if (!module.parent) {
app.listen(config.port, function () {
console.log('Express server listening on port ' + config.port);
});
}
}).catch(function (e) {
throw new Error(e);
});
config.js
var path = require('path'),
rootPath = path.normalize(__dirname + '/..'),
env = process.env.NODE_ENV || 'production';
var config = {
development: {
root: rootPath,
app: {
name: 'api-http-revo'
},
port: process.env.PORT || 3000,
db: 'mysql://localhost/api-http-revo-development'
},
test: {
root: rootPath,
app: {
name: 'api-http-revo'
},
port: process.env.PORT || 3000,
db: 'mysql://localhost/api-http-revo-test'
},
production: {
root: rootPath,
app: {
name: 'api-http-revo'
},
port: process.env.PORT || 3000,
db: {
host: '10.0.0.4', //Local Ip address on VPN
user: 'myusername',
password: 'mypassword',
database: 'db-revo',
port: 3306
}
}
};
module.exports = config[env];
ERROR on 'npm start':
Unhandled rejection Error: SequelizeConnectionRefusedError: connect
ECONNREFUSED 10.0.0.4:3306
at /home/giovannimarino/api-http-revo/app.js:20:11
at tryCatcher (/home/giovannimarino/api-http-revo/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/home/giovannimarino/api-http-revo/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/home/giovannimarino/api-http-revo/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/home/giovannimarino/api-http-revo/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/home/giovannimarino/api-http-revo/node_modules/bluebird/js/release/promise.js:689:18)
at Async._drainQueue (/home/giovannimarino/api-http-revo/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (/home/giovannimarino/api-http-revo/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues [as _onImmediate] (/home/giovannimarino/api-http-revo/node_modules/bluebird/js/release/async.js:17:14)
at processImmediate [as _immediateCallback] (timers.js:383:17)
The following screenshot are the firewall configuration:
Machine B:
Machine A
This might be due to firewall blocking your DB connections. To confirm do a telnet on the port 3306 and if it's found to be blocking then setup an inbound rule for allowing network traffic on port 3306 on both the systems.
More information here on how to setup network traffic rules.