I am trying to use my MySQL docker container with node.js using Sequelize. But I keep getting HostNotFoundError. I am able to connect to the database with MySQL Workbench.
I also tried putitng "127.0.0.1 localhost" into my host file.
Error:
C:\projects\todo-backend\node_modules\sequelize\lib\dialects\mysql\connection-manager.js:96
throw new SequelizeErrors.HostNotFoundError(err);
^
HostNotFoundError [SequelizeHostNotFoundError]: getaddrinfo ENOTFOUND
"localhost"
docker-compose.yml
version: '3.8'
networks:
mysql_app:
external: true
x-common-variables: &common-variables
MYSQL_USER: todo
MYSQL_PASSWORD: s3cret
MYSQL_DATABASE: todos
REACT_APP_SERVER_PORT: 8000
services:
mysql:
image: mysql
restart: always
environment:
<<: *common-variables
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: todos
ports:
- "3307:3306"
networks:
- mysql_app
volumes:
- C:/projects/docker/mysql:/data/pc
.env:
MYSQL_DB: "todos",
MYSQL_USERNAME: "todo",
MYSQL_PASSWORD: "s3cret",
MYSQL_HOST: "localhost",
MYSQL_DIALECT: "mysql"
MYSQL_PORT: 3307
Here I already tried "mysql", "localhost" and "127.0.0.1".
db.config.js:
const Sequelize = require('sequelize');
const sequelize = new Sequelize(process.env.MYSQL_DB, process.env.MYSQL_USERNAME, process.env.MYSQL_PASSWORD, {
host: process.env.MYSQL_HOST,
dialect: process.env.MYSQL_DIALECT,
operatorsAliases: 0,
port: process.env.MYSQL_PORT,
});
const db = {};
db.Sequelize = Sequelize;
db.sequelize = sequelize;
db.todo = require("../model/todo.model.js")(sequelize, Sequelize);
module.exports = db;
When I remove the host then it tries to connect to 172.19.0.1, which is the ip-address inside the docker container.
server.js
require('dotenv').config()
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
const PORT = process.env.PORT || 8080;
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const db = require("./app/config/db.config.js");
db.sequelize.sync({ force: true }).then(() => {
console.log("Drop and Resync with { force: true }");
});
require("./app/route/todo.route.js")(app);
app.listen(PORT, () => {
console.log(`Server is running on port: ${PORT}`)
});
Related
I developed nodeapi using docker container and when I trying to connect mysql running 'docker-compose up' throw this error.
error
my index.js
const express = require('express')
const mysql = require('mysql2');
const mysqlConfig = {
host: "cckl_mysql_server",
user: "cckl_admin",
password: "cckl_root",
database: "cckl_db",
socketPath: '/var/run/mysqld/mysqld.sock'
}
let con = null
const app = express()
app.get('/connect', function (req, res) {
con = mysql.createConnection(mysqlConfig);
con.connect(function(err) {
if (err) throw err;
res.send('connected')
});
})
docker-compose.yml
version: "3.8"
services:
cckl-app:
container_name: cckl-backend
build:
context: .
dockerfile: Dockerfile
ports:
- 8080:8080
volumes:
- .:/app
- '/app/node_modules'
depends_on:
- cckl_mysql_server
cckl_mysql_server:
image: mysql:8.0
environment:
- MYSQL_DATABASE=cckl_db
- MYSQL_USER=cckl_admin
- MYSQL_PASSWORD=cckl_root
- MYSQL_ROOT_PASSWORD=cckl_root
I am new in docker somebody hint me plz.
I am trying to get node to connect to my local mysql from within docker-compose
I have verified node connects fine from the command line, and docker compose is loading node fine - I can access functions which don't use mysql via localhost
my docker compose file
version: '3.6'
services:
mysql:
container_name: mysql
image: mysql:8.0.29
ports:
- "3306:3306"
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpw
MYSQL_USER: user
MYSQL_PASSWORD: paass
MYSQL_ROOT_HOST: "%"
MYSQL_DATABASE: cine
volumes:
- './services/db/schema:/docker-entrypoint-initdb.d'
node:
container_name: node
build:
context: ./services/node
dockerfile: Dockerfile-dev
volumes:
- './services/node:/usr/src/app'
- '/usr/src/app/node_modules'
ports:
- 3001:3001
environment:
- NODE_ENV=development
- CHOKIDAR_USEPOLLING=true
depends_on:
- mysql
client:
container_name: client
labels:
traefik.frontend.passHostHeader: 'true'
build:
context: ./services/client
dockerfile: Dockerfile-dev
volumes:
- './services/client:/usr/src/app'
- '/usr/src/app/node_modules'
environment:
- NODE_ENV=development
- CHOKIDAR_USEPOLLING=true
- REACT_APP_API_URL=${REACT_APP_API_URL}
depends_on:
- node
nginx:
container_name: nginx
build:
context: ./services/nginx
dockerfile: Dockerfile-dev
restart: always
ports:
- 3007:80
depends_on:
- node
- client
and my node file
const app = express();
const bodyParser = require('body-parser');
const PORT = 3001;
const nodemailer = require('nodemailer');
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
require('dotenv-extended').load();
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'usser',
password : 'pass!',
database : 'cine',
port : '3306',
socketPath: '/var/run/mysqld/mysqld.sock'
});
console.log('this works');
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.get('/api', function (req, res) {
res.json({ response: "hello!" });
});
app.get('/api/listfilms', function (req, res) {
sql="select * from films;";
console.log(sql);
connection.query(sql, function (error, results, fields) {
if (error) throw error;
console.log(results);
results=JSON.parse(JSON.stringify(results))
console.log(results);
if (results == ""){
var response="error";
var resp = [{
"id": 0,
"resp": response,
},];
}else{
var resp = [{
"id": results.id,
"resp": results.name,
},];
}
res.json(resp);
})
})
the error i get is
node | Error: connect ENOENT /var/run/mysqld/mysqld.sock
node | at PipeConnectWrap.afterConnect [as oncomplete] (net.js:1107:14)
I have looked at other similar posts and tried their recommendations but none appear to work
Thanks
In your node config file the host must be mysql not localhost. Since you have network configured in between containers, you just can use myql as the host of node config file
I've created a node/mysql app and i have the following docker-compose.yaml file
version: "3.4"
x-common-variables: &common-variables
MYSQL_USER: sampleuser
MYSQL_PASSWORD: samplepassword
MYSQL_DATABASE: sampledb
services:
mysql-db:
image: mysql:5.7
container_name: mysql_container
environment:
<<: *common-variables
MYSQL_HOST: localhost
MYSQL_ROOT_PASSWORD: root
ports:
- 3308:3306
restart: always
volumes:
- ./db:/docker-entrypoint-initdb.d
phpmyadmin:
depends_on:
- mysql-db
image: phpmyadmin/phpmyadmin
container_name: phpadmin_container
environment:
PMA_HOST: mysql-db
links:
- mysql-db:mysql-db
ports:
- 8080:80
restart: always
server:
build: ./server
container_name: node_server_container
ports:
- 3000:3000
volumes:
- ./server:/app
working_dir: /app
depends_on:
- mysql-db
environment:
<<: *common-variables
MYSQL_HOST_IP: mysql-db
links:
- mysql-db
now, in the server sub directory i have a small node server
require('dotenv').config()
const express = require('express');
const setRouter = require('./routes/routes');
const port = process.env.PORT || 3000;
const app = express();
setRouter(app)
app.set('port', port);
app.use('/', (req, res) => {
return res.status(200).json({ statusCode: 200 })
});
// Listen on provided port, on all network interfaces.
app.listen(port, () => console.log(`API running on localhost:${port}`));
module.exports = app;
which connect to the mysql db:
'use strict';
const mysql = require('mysql2');
const options = {
host: process.env.MYSQL_HOST_IP,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE,
};
const pool = mysql.createPool(options);
const promisePool = pool.promise();
module.exports = promisePool;
I would like to test my endpoints, and i tried using jest and supertest but i failed miserably.
I'm trying something like this:
const app = require('../app')
const request = require('supertest');
describe('GET /users/:email', function() {
it('responds with json', async function(done) {
const res = await request(app).get('/users/Jupiter#planet.it')
expect(res.headers["Content-Type"]).toMatch(/json/);
});
});
Now, if i don't provide a .env i get a console log in my users route to print the error:
Error: Access denied for user ''#'localhost' (using password: NO)
if I provide a .env
MYSQL_HOST_IP=127.0.0.1:3306
MYSQL_USER=sampleuser
MYSQL_PASSWORD=samplepassword
MYSQL_DATABASE=sampledb
then I this error: Error: getaddrinfo ENOTFOUND 127.0.0.1:3306
How do i get to connect to the running container? (note that i run the test manually from the server folder after stopping the node container, not sure if there's a better solution)
Full repo can be found here
it has been a long day and i don't know why i am stuck at this problem for such a long time so any help is very much appreciated!
my problem is the famus code: 'ECONNREFUSED' which suddenly appeared for my project. i am trying to run a mysql db with PMA in docker and trying to connect to it from my nodejs (not in docker but on host) to get a fetch response but everything that i try and any suggestion i look at i find no solution! so any idea at this point would help me greatly and get me to bed sooner.
i cut the story short and put my codes here please do let me know with any tips, thanks in advance!
this is my server.js file
const express = require('express');
const apiroutes = require('./routes');
const app = express();
app.use(express.json());
app.use('/api/data', apiroutes);
app.listen('3000', ()=>{
console.log('server is running on port: 3000');
});
this is my routes file
const express = require('express');
const db = require('../db');
const router = express.Router();
router.get('/', async(req, res, next)=>{
try{
let results = await db.all();
res.json(results);
} catch(error){
console.log(error);
res.sendStatus(500);
}
});
module.exports = router;
this is my db file
const mysql = require('mysql');
const pool = mysql.createPool({
connectionLimit : 100,
password: 'secret',
user: 'user',
database: 'db_test',
host: 'localhost',
port: '3306'
});
let wholeDB = {};
wholeDB.all = () => {
return new Promise((resolve, reject)=>{
pool.query(`SELECT * FROM table1`,(error, result)=>{
if(error){
return reject(error);
}
return resolve(result);
});
});
};
module.exports = wholeDB;
this is my dockerfile
FROM php:7.2-fpm-alpine
RUN docker-php-ext-install pdo pdo_mysql
and finaly this is my docker-compose file
version: '3'
networks:
vuePhP:
services:
nginx:
image: nginx:stable-alpine
container_name: nginxWebServer
ports:
- "8088:80"
volumes:
- ./src:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- mysql
- php
networks:
- vuePhP
mysql:
image: mysql
container_name: mysqlService
restart: unless-stopped
tty: true
ports:
- "4306:3306"
volumes:
- ./mysql:/var/lib/mysql
environment:
MYSQL_DATABASE: db_test
MYSQL_USER: user
MYSQL_PASSWORD: secret
MYSQL_ROOT_PASSWORD: root
networks:
- vuePhP
phpmyadmin:
image: phpmyadmin
container_name: phpMyAdmin
restart: always
depends_on:
- mysql
- php
environment:
- PMA_HOST=mysql
- PMA_PORT=3306
ports:
- "8081:80"
networks:
- vuePhP
php:
build:
context: .
dockerfile: Dockerfile
container_name: phpService
volumes:
- ./src:/var/www/html
ports:
- "9000:9000"
networks:
- vuePhP
and this is the error that i get when i use postman to do a get command
errno: -111, code: 'ECONNREFUSED', syscall: 'connect',
address: '127.0.0.1', port: 3306, fatal: true
Error: connect ECONNREFUSED 127.0.0.1:3306
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1157:16)
thank you!
edit: i have added the port 4306 to the node app and get this 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
i added this line in my compose file but it didn't help:
mysql:
image: mysql
container_name: mysqlService
restart: unless-stopped
tty: true
ports:
- "4306:3306"
volumes:
- ./mysql:/var/lib/mysql
environment:
MYSQL_DATABASE: KFV_test
MYSQL_USER: user
MYSQL_PASSWORD: secret
MYSQL_ROOT_PASSWORD: root
command: --default-authentication-plugin=mysql_native_password
networks:
- vuePhP
ah i found it, the problem is the version of mysql in composer and usage of mysql library instead of mysql2 as Phil graciously mentioned. so i downgraded mysql version by version until i found the one that worked and before that added mysql2 (npm i mysql2) to my nodejs app. and it worked. here my is my changes in docker-compose file. btw changed the ports as well not that it helped before the downgrade.
mysql:
image: mysql:5.7.24
container_name: mysqlService
restart: unless-stopped
tty: true
ports:
- "3306:3306"
volumes:
- ./mysql:/var/lib/mysql
environment:
MYSQL_DATABASE: db_test
MYSQL_USER: user
MYSQL_PASSWORD: secret
MYSQL_ROOT_PASSWORD: root
networks:
- vuePhP
and changed the connection method in my db file:
const mysql2 = require('mysql2');
const connection = mysql2.createConnection({
host: 'localhost',
user: 'user',
password: 'secret',
database: 'db_test',
});
let wholeDB = {};
wholeDB.all = () => {
return new Promise((resolve, reject)=>{
connection.query(`SELECT * FROM table1`,(error, result)=>{
if(error){
return reject(error);
}
return resolve(result);
});
});
};
module.exports = wholeDB;
var mysql = require('mysql')
var connection = mysql.createPool({
host: "localhost",
user: "root",
password: "",
database: "dbName",
port : "3306"
})
connection.getConnection((err, connection) => {
if (err) {
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
console.error('Database connection was closed.')
}
if (err.code === 'ER_CON_COUNT_ERROR') {
console.error('Database has too many connections.')
}
if (err.code === 'ECONNREFUSED') {
console.error('Database connection was refused.')
}
}
if (connection) connection.release()
return
})
module.exports = connection
example :
import connection from '../Modules/connection.js';
let LoginQuery = (values) => {
return new Promise((resolve, reject) => {
// let sql = `SELECT * FROM user_tbl WHERE mobile_number ="${values.mobile_number}" OR email_id="${values.mobile_number}"`;
let sql = "SELECT * FROM `admin_tbl` WHERE mobile_number = ? OR email_id = ?";
connection.query(sql, Object.values(values), (err, result) => {
console.log(err);
err ? reject(err) : resolve(result);
});
});
};
Please use this connecting pool hope it'll work.
I am trying to start mysql and nodejs with docker-compose. I am running nodejs on port 3006 and I want mysql to use the already created database which is called "locations".
When I execute docker-compose , I don't get any errors but at the console I get this output and it gets "stuck " here.
2020-12-04T23:19:20.685756Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.22' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
If I now try to start visit localhost:3006 I get the message that the site can't be reached and that the connection was reset.
This is my docker-compose file.
version: "3.2"
services:
nodejs:
build: ./
image: nodejs
container_name: nodejs_2
restart: unless-stopped
ports:
- "3006:3006"
depends_on:
- mysql
mysql:
image: mysql:latest
ports:
- 3306
environment:
- MYSQL_ROOT_PASSWORD=boom
- MYSQL_DATABASE=locations
- MYSQL_HOST=0.0.0.0
- MYSQL_PORT=3306
volumes:
- /home/stan/Documents/project:/var/lib/mysql
app.js:
// Require packages and set the port
const express = require('express');
const port = 3006;
const bodyParser = require('body-parser');
const locations_t = require('/home/stan/Documents/project/locations.js');
const app = express();
// Use Node.js body parsing middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true,
}));
locations_t(app);
// Start the server
const server = app.listen(port, (error) => {
if (error) return console.log(`Error: ${error}`);
console.log(`Server listening on port ${port}`);
});
Dockerfile:
FROM node:6.10
RUN mkdir /app
WORKDIR /app
COPY package.json /app/package.json
RUN npm install
RUN npm i -g db-migrate
EXPOSE 3006
CMD tail -f /dev/null
config.js:
const mysql = require('mysql');
const config = {
host: 'mysql',
user: 'root',
password: 'password',
database: 'locations',
};
// Create a MySQL pool
const pool = mysql.createPool(config);
var connection = mysql.createConnection({multipleStatements: true});
// Export the pool
module.exports = pool;
locations.js:
// Load the MySQL pool connection
const pool = require('/home/stan/Documents/projects/config.js');
const router = app => {
// Display welcome message on the root
app.get('/', (request, response) => {
response.send({
message: 'Welcome!!'
});
});
If i start app.js without docker-compose everything works fine but starting it with docker localhost can not be reached.
Could someone help me out?
I have been stuck on the issue for days.