Connecting a NodeJS container to a MySQL database - mysql

Before marking this post as a duplicate note that I've already looked at the other related posts here and pretty much everywhere I could without finding a solution to my precise case. I just keep getting confused between docker-compose.yml versions and linking the ports to each other.
Here's the issue:
I've created two containers with Docker, one hosting a NodeJS server, one hosting a MySQL database.
My docker-compose.yml looks like this:
version: '3'
services:
server:
build: ./server/
ports:
- "8080:8080"
depends_on:
- db
db:
build: ./db
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_ALLOW_EMPTY_PASSWORD: 1
MYSQL_DATABASE: dashboard_nodejs
MYSQL_USER: root
MYSQL_PASSWORD: password
client:
image: angular_app
build: ./front/
ports:
- "4242:80"
depends_on:
- server
When running docker-compose up, all of my apps are built and run without an issue until the server tries to connect to MySQL, exiting with :
Error: connect ECONNREFUSED 172.20.0.2:3306 at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1191:14)
The dockerfile for my database only contains
FROM mysql
COPY init_db.sql /docker-entrypoint-initdb.d/
and init_db.sql currently is
CREATE DATABASE IF NOT EXISTS dashboard_nodejs;
GRANT ALL PRIVILEGES ON dashboard_nodejs.*
TO 'root'#'%' IDENTIFIED BY 'password'
WITH GRANT OPTION;
Finally, my server attemps to establish the connection with the following parameters:
var con = mySql.createConnection({
host: "db",
user: "root",
password: "password",
database: "dashboard_nodejs"
});
I have no clue why the connection is refused by mysql even with (what looks to me like) the right credentials.
I apologize in advance if this particular case has already been discussed.

Add ports: "3306:3306" to the db service.

Related

Access denied when running migration on Prisma

I am learning Prisma and I can't do migration in my localhost.
I am using docker-compose to create an image of mysql and I have successfully connected to the DB, please see my docker-compose.yml and schema.prisma below:
Prisma's version
"prisma": "^4.6.1"
docker-compose.yml
services:
db:
image: mysql:8
volumes:
- db-data:/var/lib/mysql
ports:
- 3306:3306
networks:
- dev
environment:
MYSQL_ROOT_PASSWORD: prismatutorial
MYSQL_USER: prismatutorial
MYSQL_PASSWORD: prismatutorial
MYSQL_DATABASE: prisma_tutorial
command: mysqld --default-authentication-plugin=mysql_native_password
cap_add:
- ALL
networks:
dev:
volumes:
db-data:
driver: local
schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model User {
id Int #id #default(autoincrement())
name String
}
.env
DATABASE_URL="mysql://prismatutorial:prismatutorial#localhost:3306/prisma_tutorial"
Every time I run the command of npx prisma migrate dev --name firstMigration and I have the error as shown in the below message:
Error: P3014
Prisma Migrate could not create the shadow database. Please make sure the database user has permission to create databases. Read more about the shadow database (and workarounds) at https://pris.ly/d/migrate-shadow
Original error: Error code: P1010
User prismatutorial was denied access on the database prisma_tutorial
However, when I try to run npx prisma db push , I can see the table is successfully created in my localhost's DB and it doesn't have permission error.
I don't think I have to create a shadow database at this point.
Am I missing out something?
Or, the docker-compose.yml I have written is wrong?
Your help is very appreciated!
In this case, npx prisma db push is successfully creating the tables because it does not require a shadow database. Please note that you should use db push command for quick prototyping.
As you are using MySQL Database, the database user prismatutorial should have CREATE, ALTER, DROP, REFERENCES ON *.* privileges as per this reference. Once you grant these permissions you should be able to use migrate commands.

Connection refused on mysql with user granted on %

I see other question like this here on S.O. but no one solved my problem.
I'm running MySQL using Docker, and on the first boot, I'm running some SQL queries to prepopolate the DB. One of those is the following:
CREATE USER 'user'#'%' IDENTIFIED BY 'user';
Grant All Privileges ON *.* to 'user'#'%';
FLUSH PRIVILEGES;
However, when I try to connect to the DB from another container, I get:
SQLSTATE[HY000] [2002] Connection refused (SQL: ...)
What am I doing wrong?
This happens both if I use the name of the container, and 127.0.0.1 as host
my docker-compose looks like this:
#MySQL Service
db:
image: mysql
container_name: db
restart: unless-stopped
tty: true
ports:
- "3307:3306"
- "8001:3306"
environment:
....
volumes:
- ./database/dbdata:/var/lib/mysql/:rw
- ./config/mysql/my.cnf:/etc/mysql/my.cnf
the strangest part of all of this, is that if I connect to the DB with a MySQL client installed on my PC, the connection works fine...
my.cnf is the following:
[mysqld]
general_log = 1
general_log_file = /var/lib/mysql/general.log
secure-file-priv = NULL
bind-address = 0.0.0.0

mysql docker image how to create databases with their own username and password

I have a docker image as follows:
version: '3.6'
services:
# MySQL
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mydb
MYSQL_USER: user
MYSQL_PASSWORD: user
ports:
# <Port exposed> : < MySQL Port running inside container>
- '3306:3306'
expose:
# Opens port 3306 on the container
- '3306'
volumes:
- ./init:/docker-entrypoint-initdb.d
The init folder directory is as follows:
init
01.sql
The 01.sql is defined as follows:
CREATE DATABASE IF NOT EXISTS `test`;
GRANT ALL ON `test`.* TO 'user'#'%';
When I execute docker-compose up the two databases are created successfully, but both mydb and test are using same username and password. Is it possible to create a different user and password for test database?
update:
I have updated the script 01.sql to:
CREATE DATABASE IF NOT EXISTS `test`;
CREATE USER 'newuser'#'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON test.* TO 'newuser'#'localhost' WITH GRANT OPTION;
But when I try to connect using DBeaver(username:newuser,password:password) get the error access denied.
However when I connect using username:root, password:root i can see the table created:
Thanks in advance
Any idea what i am doing wrong please?

Can't login as root into MySQL container

I have a docker-compose file setup like this:
version: '3'
services:
database:
image: mysql:5.6
volumes:
- dbdata:/var/lib/mysql
environment:
- "MYSQL_DATABASE=my_database_name"
- "MYSQL_USER=my_database_user"
- "MYSQL_PASSWORD=my_database_password"
- "MYSQL_ROOT_PASSWORD=my_root_password"
ports:
- "33061:3306"
volumes:
dbdata:
I'm trying to login to the mysql cli client with root user & password (by first going into the container itself):
mysql -uroot -pmy_root_password
But I keep getting this error:
ERROR 1045 (28000): Access denied for user 'root'#'localhost' (using password: YES)
I didn't set the mysql root password env var from the very beginning. I had to remove the created volume "dbdata" and run docker-compose up again. That fixed it. Thanks for the help!

Can't start application within docker using linked mysql database

I'm using docker to run my nodejs app with few databases, and one of them is mysql.
I found mysql image on the docker hub and use it in my docker-compose.yml
app:
build: .
volumes:
- ./:/var/www/app/
working_dir: /var/www/app/
command: node app.js
ports:
- "3000:3000"
links:
- mongo
- elasticsearch
- mysql
mysql:
image: mysql
environment:
MYSQL_DATABASE: testdb
mongo:
image: mongo
elasticsearch:
image: elasticsearch
Everything builds and application uses mysql conenction config that seems like this:
mysql: {
host: 'localhost',
user: 'root',
password: '',
database: 'testdb'
}
Application trying to start and stops on the the mysql connection error.
Error: connect ECONNREFUSED 127.0.0.1:3306
I'm wondering if docker mysql image could be linked to the app container via compose file. Please explain how to link mysql container properly.
Thanks in advance!
My own answer
When you're using any type of linking other containers(external_link or link) you may set in your application config file the process environment variables according to the name of the container
process.env.<container_name>_PORT_<container_port>
SailsJS to Mongo Example:
I have a container with name mongo_dev which is connected in my docker compose file as
external_links:
- mongo_dev
so in my application config this environment variable used like this:
mongo: {
module : 'sails-mongo',
host : process.env.MONGO_DEV_PORT_27017_TCP_ADDR || 'localhost',
port : process.env.MONGO_DEV_PORT_27017_TCP_PORT || '27017',
user : null,
password : null,
database : 'database_name'
}
The linked mysql container will be your mysql host
mysql: { host: 'mysql', user: 'root', password: '', database: 'testdb' }
You will see all you linked hosts are named in /etc/hosts like:
172.17.0.2 composetest_mysql_1 fffb39e63df6
172.17.0.2 mysql fffb39e63df6 composetest_mysql_1
172.17.0.2 mysql_1 fffb39e63df6 composetest_mysql_1
Use Connection String as Follows:
mysql://username:password#mysql:3306/demo