I’m a beginner with Docker and trying it out with Ubuntu 20.04.3 LTS , Docker 20.10.8 , MySQL 8.0.26 (installed on the host).
I have a containerized nodejs trying to mysql.createPool({host: 'host.docker.internal', ...}) but I got:
Error: connect ECONNREFUSED 127.0.0.1:3306
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1144:16)
at Protocol._enqueue (…/node_modules/mysql/lib/protocol/Protocol.js:144:48)
at Protocol.handshake (…/node_modules/mysql/lib/protocol/Protocol.js:51:23)
at PoolConection.connect (…/node_modules/mysql/lib/Connection.js:116:18)
at Pool.getConnection (…/node_modules/mysql/lib/Pool.js:48:16)
Could there be a bug in the mysql client in the node:12-alpine image? I’ve checked that docker exec -it ... ping host.docker.internal is indeed resolved as 172.17.0.1. Why is mysql.createPool({host: 'host.docker.internal', ...}) trying to look for 127.0.0.1:3306?
Despite that error, I was able to reach another container on the same host with host.docker.internal. I believe it proves that I have run --add-host=host.docker.internal:host-gateway correctly.
I’ve even built another image with 172.10.0.1 hardcoded in createPool() and run the js in a container, but to no avail.
To check that the problem didn’t stem from my js, I ran the js standalone (on the host) by node xyz.js with localhost and 127.0.0.1 supplied to createPool(), both were able to connect to MySQL. Then I did a crazy experiment by supplying 172.10.0.1 to createPool() and ran the js standalone, it gave connect ECONNREFUSED 172.17.0.1:3306 BUT if I and add 172.17.0.1 host.docker.internal to /etc/hosts(on the host) and supply host.docker.internal to createPool(), the js could connect to MySQL standalone!
What am I missing with the containerized js? Why couldn’t it reach MySQL on the host? Any idea? Thanks!
I use host.docker.internal on Docker for Windows to connect to the host from within a container.
To do the same on Docker for Linux I use 172.17.0.1 (with default networking) or localhost (with --net=host).
To use the same host.docker.internal on Docker on Linux with default-networking-settings you can start your container with --add-host=host.docker.internal:172.17.0.1 or use these lines in your docker-compose.yml
extra_hosts:
- "host.docker.internal:172.17.0.1"
172.17.0.1 is the IP-address of the host in Docker’s default network.
Unfortunately it gave the same result, I was using run --add-host=host.docker.internal:host-gateway, I tried your suggestion --add-host=host.docker.internal:172.17.0.1 too but to no avail.
I’m still getting
Hello,
sorry for forgetting one (maybe important) thing:
by default MySQL/MariaDB installed on a host is only listening to localhost. But when you try to access from a container you are accessing it from a different IP.
So you need to configure the database-service to listen to other/all ip-addresses.
And you may need to modify your user to be allowed to access from other ip-addresses, too.
done a test:
have started my container (on Linux) with docker run -it --add-host=host.docker.internal:172.17.0.1 node:12-alpine ash
installed the mysql-module with npm install mysql and then created this mysqltest.js
var mysql = require('mysql');
var pool = mysql.createPool({
connectionLimit : 100,
host : 'host.docker.internal',
user : 'xxxx',
password : 'xxxx',
database : 'xxxx',
debug : false,
timezone : 'cet'
});
pool.getConnection(function(err,connection){
if(err) {
res.json({"code" : 100, "status" : "Error in connection database"});
return;
}
console.log('connected as id ' + connection.threadId);
try{
sql = 'select count(*) as anz_docs from kb_docs';
connection.query(sql, function(err, rows, fields) {
if (!err) {
var num_found = rows[0]['anz_docs'];
console.log('num_found');
console.log(num_found);
}
});
}
finally{
connection.release();
}
});
When running this with node mysqltest.js I got the following result:
connected as id 662
num_found
2065
which is what I expected.
Please check that the object passed to mysql.createPool contains the host only once and not multiple times with different values.
Hi @matthiasradde thanks for the hint! I looked into my MySQL config and it’s working now.
This is what I have done:
a) under /etc/mysql/mysql.conf.d/, mysql.cnf is a blank file; mysqld.cnf had bind-address and mysqlx-bind-address both = 127.0.0.1, I changed only the bind-address to 127.0.0.1,host.docker.internal thensystemctl restart mysql
b) added an entry 172.17.0.1 host.docker.internal to /etc/hosts before
c) CREATE USER 'reader'@'%' IDENTIFIED WITH mysql_native_password BY 'xxxxx'