mysql host not resolving with docker container for Nodejs and express - mysql

I'm trying to use NodeJS+Express, MySQL, phpmyadmin altogether. phpmyadmin itself resolving the address by port 8183 in my situation. But whenever I'm going to connect it through with mysql js package of NodeJS. it is not working and throwing error
Error: connect ECONNREFUSED 127.0.0.1:3306
Note: I tried with few variations as host anyone didn't work for me!
example: mysql, my_machine_ip, localhost, 0.0.0.0
nothing worked for me.
Here's my yml file.
version : '3'
services:
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: node_pa
links:
- mysql
depends_on:
- mysql
environment:
PMA_HOST: mysql
PMA_PORT: 3306
PMA_ARBITRARY: 1
restart: always
ports:
- 8183:80
node_backend:
container_name: node_with_pa_msql
build: ./backend_app
# volumes:
# - ./backend_app:/usr/src/app
links:
- mysql
depends_on:
- mysql
restart: on-failure
ports:
- 3004:4006
mysql:
image: mysql:latest
container_name: node_mysql
# volumes:
# - backend_app/db_sample:/docker-entrypoint-initdb.d
environment:
MYSQL_USER: user
MYSQL_PASSWORD: user
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: default_schema
And mysqlJS connection details
// environment variables
const PORT = process.env.PORT || 4006;
const HOST = process.env.HOST || 'localhost';
// // mysql credentials
const connection = mysql.createConnection({
host: HOST,
user: process.env.MYSQL_USER || 'root',
password: process.env.MYSQL_PASSWORD || 'root',
connectTimeout: 20000
});
So, phpmyadmin is working and i can access databases/create/delete/edit by that so this assure that mysql itself also working, But right now I'm unable to connect it with mysqlJS of my nodejs app.
here's the sample project with the problem if you would like to try on your machine project GitHub link with YAML file
Note: Check answer added a complete solution of this issue.

I'm assuming the phpMyAdmin instance is working since you are actually passing the env var PMA_HOST and PMA_PORT correctly to the container.
You will need to do the same for the JS application, so your docker-compose config will look like the following:
node_backend:
container_name: node_with_pa_msql
build: ./backend_app
# volumes:
# - ./backend_app:/usr/src/app
environment:
MYSQL_HOST: mysql
MYSQL_PORT: 3306
links:
- mysql
depends_on:
- mysql
restart: on-failure
ports:
- 3004:4006
Then in your JS code you need to get the connection information from your env variables:
// environment variables
const PORT = process.env.MYSQL_PORT || 4006;
const HOST = process.env.MYSQL_HOST || 'localhost';
// // mysql credentials
const connection = mysql.createConnection({
host: HOST,
port: PORT,
user: process.env.MYSQL_USER || 'root',
password: process.env.MYSQL_PASSWORD || 'root',
connectTimeout: 20000
});
This works because when you link the mysql container, a hosts entry is added to your js container which makes the hostname mysql point to the (docker internal) ip address of the mysql container.

Finally after a big mess, solved this issue!
With stated above YAML file. everything is almost OK, But the main problem is order of image.
That means I have total 3 image from them node is dependent to mysql. So first mysql must has to start so then you can get the connection of mysql and use it with your application (nodeJS). This is the reason why any host were not resolving with my implementation.
I followd this article: https://docs.docker.com/compose/startup-order/
and for implementation example this: https://dev.to/hugodias/wait-for-mongodb-to-start-on-docker-3h8b
You are done! now use your desired driver
Now
this is node (mysqlJS) package specific. the package by itself doesn't support latest mysql and if you use latest tagged mysql mysql:latest then you may face this issue.
Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client docker mysql node
quick solution downgrade it to lower until it works. I'm not sure about minimum version but mysql:5.6 works!
If you want a quick starter with everything phpmyadmin,mysql,nodejs app
then you can use this repo: Here

Related

Database on my discord bot (Discord.js + mysql)

Well, I am making a discord bot and I want to implement a mysql database on it.
I've researched how to connect an online database on my bot that use Node.js, but I've failed.
I want to know whether I have to install MySQL on my computer or there is a way to connect it online. I'm very confuse.
One more thing: If I have to install it on my PC, is there a way to upload the bot and the database together?
Help me, please.
(I'm Brazilian, so some words or sentences may be wrong)
You can use the NodeJS MySQL client for connecting to your database:
const { createConnection } = require('mysql');
const database = createConnection({
host: 'localhost',
user: 'user',
password: 'password',
database: 'db',
});
database.connect();
As for installing and setting up MySQL, between a local install and a containerized install, I'd recommend containerizing it with Docker.
This can get you started via docker-compose: docker-compose up.
# docker-compose.yml
version: '3'
services:
db:
image: mysql:8.0
restart: always
environment:
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- '3306:3306'
expose:
- '3306'
volumes:
- database:/var/lib/mysql
volumes:
database:

Symfony; SQLSTATE[HY000] [2002] No such file or directory while using 127.0.0.1 as database_host

The full error is Doctrine\DBAL\Exception\ConnectionException: An exception occurred in driver: SQLSTATE[HY000] [2002] No such file or directory in /app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php on line 113, but that's too long for the title.
I'm trying to set up a Symfony project locally, but I'm struggling to get the database connection to work. My parameters.yml looks as follows
parameters:
database_host: 127.0.0.1
database_port: 3306
database_name: database_name
database_user: username
database_password: password
I've been googling this issue a lot and most people seem to solve the issue by changing database_host from localhost to 127.0.0.1, but this doesn't work for me. The app itself runs via Docker, but I've set up the database connection once via Brew and once with a MySQL server for Mac. In both cases I can connect via the command line and with SequelPro/TablePlus, but whenever I try to access the website through the browser I get the "No such file or directory" error.
I've also tried multiple ways of setting up a Docker MySQL container, but can't get it to work. My docker-compose.yml looks like this;
nginx:
build: nginx
ports:
- "8080:80"
links:
- php
volumes:
- ../:/app
php:
build: php-fpm
volumes:
- ../:/app
working_dir: /app
extra_hosts:
- "site.dev: 172.17.0.1"
services:
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: 'database_name'
MYSQL_USER: 'username'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password_root'
ports:
- '3306:3306'
expose:
- '3306'
volumes:
- my-db:/var/lib/mysql
But whenever I run docker-compose up -d I get the error Unsupported config option for services: 'db'.
Another attempt was adding
mysql:
image: mysql:latest
volumes:
- mysql_data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD='password'
- MYSQL_DATABASE='database_name'
- MYSQL_USER='username'
- MYSQL_PASSWORD='password'
To the docker-compose file, and while it does build the mysql image, I can't seem to connect to it with SequelPro/TablePlus. I ran docker-inspect on the container to get the IP (172.17.0.3), but can't seem to get access to it. I can exec into it, login using mysql -u root and create the required user and database, but then I'm still struggling to actually connect to it.
Running docker ps does show the sql container running btw;
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b6de6030791d docker_nginx "nginx -g 'daemon of…" 19 minutes ago Up 14 minutes 0.0.0.0:8080->80/tcp docker_nginx_1
f26b832bb005 docker_php "docker-php-entrypoi…" 19 minutes ago Up 14 minutes 9000/tcp docker_php_1
6c2a9e657435 mysql:latest "docker-entrypoint.s…" 19 minutes ago Up 14 minutes 3306/tcp, 33060/tcp docker_mysql_1
I also thought it might be an issue with changes to the parameters.yml file not properly syncing with the container as I'm using Mac (at my old workplace we had to use docker-sync to make sync changes between our dev environment and the actual container), but when inspecting the container itself using exec I can see the changes in the parameters.yml file.
Could the issue be it trying to connect to a mysql server running outside the Docker container? I'm still very new to Docker so I wouldn't be surprised if that's the mistake. Any tips are appreciated 'cause I'm at a dead end.
Your docker-compose file looks wrong to me, try below docker-compose file.
I removed the links, network is much easier.
version: '3'
services:
nginx:
build: nginx
ports:
- "8080:80"
networks:
- backend
volumes:
- ../:/app
php:
build: php-fpm
volumes:
- ../:/app
working_dir: /app
networks:
- backend
extra_hosts:
- "site.dev: 172.17.0.1"
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: 'database_name'
MYSQL_USER: 'username'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password_root'
networks:
- backend
ports:
- '3306:3306'
volumes:
- ./my-db:/var/lib/mysql
networks:
backend:
driver: bridge
then use database_host: db in php file.
I would diagnose
Check docker logs in the mysql container => no errors
Login to the mysql container and login to mysql => no errors
Login to mysql from the host (mysql -u username -p since you are mapping to 3306 port of the host)
Make sure mysql.cnf doesn't block connect from outside(check
bind-address in the mysql configuration if it 127.0.0.1 the its only
allow to connect form locally, i would for now make it 0.0.0.0 or
commented that line if exists)
mysqld --verbose --help => you will see all options
mysqld --verbose --help | grep bind-address=> check the bind-address
Make sure the user i tried to login has enough privileges to
connect(SELECT user,host FROM mysql.user;) check your user can
connect from docker network => 172.* or anywhere=> %
I think your issue is with your parameters.yml:
parameters:
database_host: 127.0.0.1
When you run compose, MySQL and PHP will run in their own containers which will have their own IPs: 127.0.0.1 or localhost from the php won't be able to connect to the db container. It's like you deployed PHP on a virtual machine A and MySQL to another virtual machine B, but you try to access MySQL from machine A by using localhost where you should specify machine B IP or hostname.
With Docker Compose the internal DNS will resolve the service name to it's container, so you can use something like:
parameters:
# name of the service in compose should be resolved
database_host: db
The error SQLSTATE[HY000] [2002] No such file or directory may be caused when the client tries to read MySQL socket usually present at /var/lib/mysql/mysql.sock which is probably not present in your PHP container.

Docker django mysql.sock in different location

I'm trying to containerize my django file, and I keep running into the issue:(2006, ’Can\‘t connect to local MySQL server through socket \‘/var/run/mysqld/mysqld.sock\’ (2 “No such file or directory”)
I found out later mysql.sock is in this location:/tmp/mysql.sock instead of /var/run/mysqld/mysqld.sock, how do I change the location for docker to see /tmp/mysql.sock
Here is my docker-composr.yml:
version: '3'
services:
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: somepassword
adminer:
image: adminer
restart: always
ports:
- 8080:8080
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
I have followed the instructions on the mysql docker website to link mysql instance to a container
EDIT: I read another stack overflow similar to this, I changed my django code to 'HOST': '127.0.0.1' in DATABASES now I get : (2006, 'Can\'t connect to MySQL server on \'127.0.0.1\' (111 "Connection refused")')
Your host should be db. When using docker-compose, you address different servers by their service name.
So, in settings.py, you should have:
DATABASES = {
'default': {
'HOST': 'db',
...
}
}
If you want to connect to your containerized MySQL server both inside and outside of the container, you'll first need to make sure the port is mapped on the host machine:
services:
db:
image: mysql
ports:
- "3306:3306"
...
That will allow you to access MySQL using localhost or 127.0.0.1 directly on your host machine.
If you want to be able to run Django in both the web container and also on the host, you'll need to override the DATABASES setting depending upon the scenario. The web container will need to use a HOST value of db, whereas your local machine will need a value of localhost.

Connecting NodeJS Docker container to a MySQL Docker container - docker-compose 3

When I try to connect two docker containers on the same machine, one running a node.js server and the other running mysql dbms
I get the following error:
(node:32) UnhandledPromiseRejectionWarning: Error: getaddrinfo ENOTFOUND jdbc:mysql://localhost:3306 jdbc:mysql://localhost:3306:3306
mysql driver connection config
const connection= mysql.createConnection({
host: 'jdbc:mysql://topsectiondb:3306',
user: 'root',
password: 'rootpass'
})
docker-compose.yml
version: '3'
services:
topsection:
container_name: topsection-server
restart: always
build: .
ports:
- '7777:7777'
depends_on:
- topsectiondb
environment:
- PORT=7777
topsectiondb:
container_name: topsectiondb
image: mysql:8.0.3
ports:
- '3306:3306'
environment:
- MYSQL_ROOT_PASSWORD=rootpass
Dockerfile
FROM node:10
RUN mkdir serviceFolder
WORKDIR /usr/app/
COPY . .
RUN npm install
EXPOSE 7777
CMD ["npm", "start"]
for a more complete stack trace
https://gist.github.com/armouti/877a8b4405330c44e4009ebae3df822c
First of all there are a couple of problems here.
Firstly you need to look at networking your docker containers in your docker-compose file together. Basically each container doesn't know of the other until you specify which network they are in. Each container can be in multiple but if you want two containers to connect they need to be in the same network. https://docs.docker.com/compose/networking/#configure-the-default-network
Then Secondly you can't use localhost as a url. Basically a docker container is an isolated environment so it has it's own "localhost" so when you use that address it's actually trying to connect to the mysql on the nodejs container. So when networked properly you will be able to connect to the mysql container using their names you gave them in the docker-compose something like topsectiondb:3306 or something like this. This tells docker your using networking to connect one docker container to another and will allow you to make the initial connection. Connect to another container using Docker compose
===================================================
Actual Answer:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
Basically the mysql library requires a hostname, which in most cases is localhost, but as your linking containers with docker-compose you use the alias of the container. The port number is 3306 by default
So:
host: "topsectiondb" will suffice!

Can't connect to mysql in docker container from phpbb

My docker container is working nicely, and I can connect to my database using my graphical sql client.
However when I try to connect to my phpbb instance, I get this error:
General Error SQL ERROR [ mysqli ]
No such file or directory [2002]
An sql error occurred while fetching this page. Please contact an
administrator if this problem persists.
The phpbb config looks like this:
$dbms = 'mysqli';
$dbhost = 'localhost';
$dbport = '';
$dbname = 'xxxxx_xxxx';
$dbuser = 'xxxxxxxxx';
$dbpasswd = 'xxxxxx';
Would the file or directory it can't find relate to the mysql.so? If so where would I set this in the docker configs?
It not then does anyone know what's going on?
Edit for clarity:
My docker-compose.yml looks like the below and I am running it with 'docker-compose up'
php:
image: webdevops/php-nginx
links:
- db:database
volumes:
- "/home/xxx/code/mytest:/mytest-now"
ports:
- 80:80
environment:
- WEB_DOCUMENT_ROOT=/mytest/public
db:
image: mariadb:latest
volumes:
- "mytest-db:/var/lib/mysql"
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: admin
MYSQL_DATABASE: dbname
MYSQL_USER: user
MYSQL_PASSWORD: password
The reason your connection is not working is the use of localhost. I assume you ran your mysql container either through docker-compose or docker and mapped port 3306 form host to 3306 on container.
Now using the graphical GUI you use localhost:3306 and it works, this is because your forwarded the docker port to the host port.
But your phpbb container the localhost refers to the container itself and hence the connection cannot be made. So there few ways to get it working
Host IP
Use the host IP which where you have mapped the port 3306
$dbhost = '192.168.0.102';
This is not a recommended approach as your host IP will change when you connect to different networks
Use mysql container name
Run your mysql container with a --name mysqldb and use the this name in the connection
$dbhost = 'mysqldb';
Use mysql service name
If you use docker-compose and added mysql as a service
version: '3'
services:
mysqldb2:
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=root
phpbb:
.....
Then you can use the service name in your connection settings
$dbhost = 'mysqldb2';
After running 'docker inspect containername' I noticed an ip address under:
NetworkSettings.Networks.bridge.gateway.
When I tried that, it worked!