express/Node testing calls to mysql from local vs docker container - mysql

I am trying to make day-to-day development easier by being able to run my code on my local directly and then deploying to a container and then testing it via container. I am using a simple Express/NodeJS application that connects to a local mysql instance using both a local run directly using node and docker run via container
Local
When I create this config to connect to MYSQL via my local I am able to connect just fine (using localhost as a host)
const connection = mysql.createConnection({
host: 'localhost',
port: 3306,
user: 'user',
password: 'user-password'
});
Using node server.js
Local using Docker
When I create this config to connect to MYSQL via my local I am able to connect just fine (my-db is the mysql service name in my docker-compose.yml since i cannot use localhost.
const connection = mysql.createConnection({
host: 'my-db',
port: 3306,
user: 'user',
password: 'user-password'
});
Using docker-compose run <myimage>
The Problem
I have to constantly keep changing my connection code to switch between localhost and my-db when running locally against node server vs running via docker-compose run . Is there a way I can make the connection agnostic of how I am running the server?

This is a good use for an environment variable. A setup I find works well is to make host names like this configurable via environment variables, falling back to defaults that will make sense for developers who may not have them set.
const connection = mysql.createConnection({
host: process.env.MYSQL_HOST || 'localhost',
port: process.env.MYSQL_PORT || 3306,
...
});
If you just npm run start your application without setting those environment variables, you'll get those defaults. But in a Docker setup, it's easy to specify them; for example in Compose
version: '3.8'
services:
database:
image: mysql:8
application:
build: .
environment:
- MYSQL_HOST=database
This setup also helps you out if you're going to deploy to a production environment where your database is running on a separate host with its own backup strategy, or a cloud-hosted database like Amazon RDS; you can just set $MYSQL_HOST to point at the database host name, without changing your code.

Related

Cannot access MySQL container in VPS from MySQL Workbench In My PC

I've created a docker container that runs MySQL on it and exposes it on the default port (3306) on a DO droplet (Ubuntu 20).
I tried accessing it on my laptop with the following parameters:
Hostname: (VPS's IP address. I also tried Public Gateway IP)
Connection: Standard (TCP/IP)
Port: 3306
Username: root
Password: (Password I have set while creating the container)
The error message just says "Could not connect to localhost"
Am I missing a step that maybe exposes the container to the internet?
After a couple of hours, I found out that the docker run command has to have -p parameter. -p=3306:3306 in my case.

NodeJS xdevapi - Creating Connection to MySQL Database

I've been using the official MySQL NPM package found here: https://www.npmjs.com/package/#mysql/xdevapi.
However, I can't seem to make a connection to the server. Here's the current error message I get:
Error: The server connection is not using the X Protocol.
Make sure you are connecting to the correct port and using a MySQL 5.7.12 (or higher) server intance.
Here is the code that generates that issue:
const db = mysqlx.getSession('root#localhost:33060/schemaname').then(session => {
console.log('SESSION STARTED!!');
});
This is just a test database without a password so I don't think the password is the issue. Also, I've made sure I'm using the right port and the MySQL version is 8.x.x so I don't think that is the issue. I created a database using the app Dbngin and I verified I could connect to the database by running the following command in my terminal: mysql -u root -h 127.0.0.1 --port=33060 -p which worked. I'm also running this on my Mac.
Update:
I've also tried passing a config object without much luck:
const config = {
user: 'root',
password: '',
host: 'localhost',
port: 33060,
schema: 'schemaname'
};
const db = mysqlx.getSession(config).then(session => {
console.log('SESSION STARTED!!');
});
Unfortunately, this code produces the same error above.
I tried it out myself and got the same error because you are using the wrong port. It could be you changed the default port, but the default port is: 3306 and not 33060 although I have to use port 33060 while my port is 3306.
X-protocal requires you to multiply your port by 10 I see here: https://dev.mysql.com/doc/mysql-port-reference/en/mysql-ports-reference-tables.html. So if your original port is 33060 I guess it should be 330600.
You could try this command SHOW VARIABLES LIKE 'mysqlx_port';

Cannot connect from Sequalize.js, can connect from MySQL client

I've got two docker services, one running a simple node server and the other a mysql (mariadb actually) database server.
All instances of a socket file mentioned anywhere in /etc/mysql/ say
/var/run/mysqld/mysqld.sock
This will be important soon.
My node server is running some Sequelize code that is trying to connect to the MySQL server.
Whenever I try and connect via Sequelize, I get:
{"statusCode":500,"error":"Internal Server Error","message":"connect ENOENT /var/run/mysqld/mysqld.sock"}
However, if I log into the Node docker container I can successfully connect to MySQL on the other docker container using the mysql CLI client.
I think I understand that the mysql client is using a tcp connection, while Sequelize is using a socket connection. But, when Sequelize is throwing that error, it is showing the correct socket path, as far as I know. Here is my Sequelize config:
const options = {
host: "mysql",
dialect: "mysql",
dialectOptions: {
socketPath: "/var/run/mysqld/mysqld.sock"
}
};
let sequelize = new Sequelize("ibbr_dev", "devuser", "password", options);
The MySQL socket file is not available in your Node container, it is only available in the MySQL container as it is a file. Rather than setting up unix socket based connection, you should use a TCP connection (skipping the dialectOptions).

Docker nodejs with mysql communication

I'm using 2 docker images one with my nodeJS backend server the other with my MySQL database. On the docker-compose file I'm defining the passwords, ports and hostnames correctly:
sql:
image: mysql:5.7.22
hostname: sql
ports:
- 3306:3306
secrets:
- db_root_pass
- db_user_pass
environment:
MYSQL_USER: user
MYSQL_PASSWORD_FILE: /run/secrets/db_user_pass
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_pass
provider:
image: monokilho/app:dev
hostname: provider
ports:
- 3000:3001
- 9221:9229
secrets:
- db_user_pass
command: node --inspect=0.0.0.0:9229 appModule.js
And on my DB_config.js file for NodeJS I have the connection setup like so:
db_config.host = 'sql';
db_config.port = '3306';
db_config.user = 'user';
db_config.password = fs.readFileSync('/run/secrets/db_user_pass', 'utf8');
db_config.database = 'app';
db_config.multipleStatements = true;
Problem is that although, using this exact configurations, docker connects Node to MySQL just fine on my local windows machine, when I upload the images to my remote linux server I continue to get:
Access denied for user 'user'#'8b2e56e566b2.network_default'
I've already remade the secrets, tried manually adding the passwords to the config on NodeJS and nothing... what makes it even weirder is that if I go on the MySQL container to connect directly or if I make another MySQL container and remotely connect it works, so I know the password input on MySQL config is correct and it is accepting remote connections.
Any suggestion what might be the difference between windows and linux for this behavior to happen? Thanks in advance.
PS: If needed windows is windows 10 and linux distro is ububtu 16.04.
EDIT: The access denied error appears on the mysql logs so the nodejs docker can reach the mysql docker and the network should be fine.
Apparently the mysql config was ignoring a sneaky \n on the password file allowing it to work normally with a command line connection, while on the nodejs it was bugging the connection.

Cloud9 IDE: Cannot Connect to MySQL via Node

I do all my web development projects using Cloud9 (which is actually part of AWS now). Anyways I have had no problem connecting using the built in PHP functions and variables but the Node platform has been giving me some trouble. The Cloud9 community guide for connecting to MySQL was much more clear for PHP than Node, and other questions and answers I have found online have had a large array of suggests but none have worked. Here is what I would have considered my best bet:
var connection = mysql.createConnection({
host: process.env.IP,
user: process.env.C9_USER,
password: "",
port: 3306,
database: "database_name"
});
Start aws cloud9 mysql service with the code:
sudo service mysqld start
Then "host" and "password" has to be used as seen below.
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '*******',
database : 'database_name'
});
That is the link for how to install and start mysql service in aws cloud9 in case of anyone needs.
aws cloud9 mysql service installation