Infrastructure setup:
Docker Desktop environment running on MacOS,
A Minikube cluster is also running on this MacOS.
Jenkins pod running on the Minikube cluster
I have this NodeJS application that talks to a MySQL database(A docker container) to retrieve a text string from a database called hello_world. I need to encrypt the database password before building the application within a NodeJS image. This image will then be pushed to the DockerHub repository.
It will then be downloaded and installed as a pod in the Minikube cluster via a Jenkins Pipeline in the dev namespace. There is a MySQL database pod already setup in the ‘dev’ namespace in which subsequent stages in the pipeline will test the retrieval of the text string from the database.
➜ nodejs-app git:(main) ✗ cat app.js
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const mysql = require('mysql');
// parse application/json
app.use(bodyParser.json());
//create database connection
const conn = mysql.createConnection({
host: 'dev-mysqldb',
user: 'mysqluser',
password: ‘xxxxxxxx’,
database: 'hello_world'
});
//connect to database
conn.connect((err) =>{
if(err) throw err;
console.log('Mysql Connected...');
});
//show all products
app.get('/',(req, res) => {
let sql = "SELECT * FROM messages";
let query = conn.query(sql, (err, results) => {
if(err) throw err;
// res.send(JSON.stringify({"status": 200, "error": null, "response": results}));
res.send(results);
});
});
//Server listening
app.listen(80,() =>{
console.log('Server started on port 80...');
});
I have 2 questions here.
How do I encrypt the database password in the above NodeJS application?
How do I make Kubernete pod decrypt the database password which was originally setup in the docker environment?
Thanks.
The simplest approach here is to use dotenv.
Usage:
Create a .env file in the root of your project:
S3_BUCKET="YOURS3BUCKET"
SECRET_KEY="YOURSECRETKEYGOESHERE"
As early as possible in your application, import and configure dotenv:
require('dotenv').config()
console.log(process.env) // remove this after you've confirmed it working
.. or using ES6?
import 'dotenv/config' // see https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import
import express from 'express'
make sure to take a look at https://github.com/motdotla/dotenv#readme for more information.
I was trying to connect to Mysql DB from cypress, did the following steps for the same.
Step 1: Added MySQL library in cypress
Step 2: Added following code in plugins/index.js file (This I have got while searching in google)
const mysql = require('mysql')
function queryTestDb(query, config) {
// creates a new mysql connection using credentials from cypress.json
env's
const connection = mysql.createConnection(config.env.db)
// start connection to db
connection.connect()
// exec query + disconnect to db as a Promise
return new Promise((resolve, reject) => {
connection.query(query, (error, results) => {
if (error) reject(error)
else {
connection.end()
// console.log(results)
return resolve(results)
}
})
})
}
module.exports = (on, config) => {
// Usage: cy.task('queryDb', query)
on('task', {
queryDb :query => {
return queryTestDb(query, config)
},
})
}
Step 3: Added the following dependencies in cypress.json
"env" : {
"db": {
"host": "name",
"user": "user",
"password": "password"
}
}
Step 4: Added the following code in the spec.js file
it('Verify the retrieved data', () => {
cy.task('queryDb','select * from soandso where soandso = value').then((resp) => {
console.log(resp.rows)
})
})
But while running the spec file getting the below error
cy.task('queryDb') failed with the following error: > ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
Please help me to fix this error.
can you check your dependency in the package.json?
It should have sth like below.
"dependencies": {
"mysql": "^2.18.1"
}
If you do not have this dependency, you need to run 'npm install mysql'
I have deployed an NodeJS (with ExpressJS, Sequelize) to Azure App Services. The simple APIs with no database connection work, however when I use the part of the app where I load the data from my Azure MySQL Database, it's having problem with certificate. I get this log message from App Service Log Stream:
Unhandled rejection SequelizeConnectionError: unable to get local issuer certificate
I have followed the steps from here on how to enable firewall and use the certificate (BaltimoreCyberTrustRoot.crt.pem).
Using the same instruction, from my laptop, I can connect to the remote Azure MySQL database, using this CLI:
$ mysql -h <my-db>.mysql.database.azure.com -u <my-user> --ssl-mode=REQUIRED --ssl-ca=.\BaltimoreCyberTrustRoot.crt.pem -p
I have followed other StackOverflow / Github questions related to this and I followed their configurations like this:
const mysql = require('mysql2');
...
var sequelize = new Sequelize(config.db, config.username, config.password, {
host: "<my-db>.mysql.database.azure.com",
port: 3306,
dialect: 'mysql',
dialectOptions: {
ssl: {
ca: fs.readFileSync(__dirname + "/ssl/BaltimoreCyberTrustRoot.crt.pem")
}
}
});
Do I need to set additional key/cert under ssl?
ssl: {
key: fs.readFileSync(__dirname + "./certs/client-key.pem"),
cert: fs.readFileSync(__dirname + "./certs/client-cert.pem"),
ca: fs.readFileSync(__dirname + "/ssl/BaltimoreCyberTrustRoot.crt.pem")
}
I am using Node 12 (Node 12.13 in Azure App Service) and here's my package.json dependencies:
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1",
"faker": "^4.1.0",
"mysql2": "^2.1.0",
"sequelize": "^5.21.5"
}
According my test, I can connect to mysql. You can add additional key/cert yes or not.
If you add, you can see my code like below,
/*configuration*/
const sequelizeInstance = new Sequelize("***db", "azure_root#***mysql", "Ja***.****20", {
host: "***mysql.mysql.database.azure.com",
dialect: 'mysql',
dialectOptions: {
ssl: {
ca: fs.readFileSync(path.resolve(__dirname, 'BaltimoreCyberTrustRoot.crt.pem'));
}
}
});
/*test connection*/
try
{
sequelizeInstance.authenticate();
console.log('Connection has been established successfully.');
}
catch (error) {
console.error('Unable to connect to the database:', error);
}
If not, you just set ssl=true like the document .
Hope it's useful to u.
I've just started getting into Node.js. I come from a PHP background, so I'm fairly used to using MySQL for all my database needs.
How can I use MySQL with Node.js?
Check out the node.js module list
node-mysql — A node.js module implementing the MySQL protocol
node-mysql2 — Yet another pure JS async driver. Pipelining, prepared statements.
node-mysql-libmysqlclient — MySQL asynchronous bindings based on libmysqlclient
node-mysql looks simple enough:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'example.org',
user : 'bob',
password : 'secret',
});
connection.connect(function(err) {
// connected! (unless `err` is set)
});
Queries:
var post = {id: 1, title: 'Hello MySQL'};
var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) {
// Neat!
});
console.log(query.sql); // INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL'
node-mysql is probably one of the best modules out there used for working with MySQL database which is actively maintained and well documented.
Since this is an old thread just adding an update:
To install the MySQL node.js driver:
If you run just npm install mysql, you need to be in the same directory that your run your server. I would advise to do it as in one of the following examples:
For global installation:
npm install -g mysql
For local installation:
1- Add it to your package.json in the dependencies:
"dependencies": {
"mysql": "~2.3.2",
...
2- run npm install
Note that for connections to happen you will also need to be running the mysql server (which is node independent)
To install MySQL server:
There are a bunch of tutorials out there that explain this, and it is a bit dependent on operative system. Just go to google and search for how to install mysql server [Ubuntu|MacOSX|Windows]. But in a sentence: you have to go to http://www.mysql.com/downloads/ and install it.
Here is production code which may help you.
Package.json
{
"name": "node-mysql",
"version": "0.0.1",
"dependencies": {
"express": "^4.10.6",
"mysql": "^2.5.4"
}
}
Here is Server file.
var express = require("express");
var mysql = require('mysql');
var app = express();
var pool = mysql.createPool({
connectionLimit : 100, //important
host : 'localhost',
user : 'root',
password : '',
database : 'address_book',
debug : false
});
function handle_database(req,res) {
pool.getConnection(function(err,connection){
if (err) {
connection.release();
res.json({"code" : 100, "status" : "Error in connection database"});
return;
}
console.log('connected as id ' + connection.threadId);
connection.query("select * from user",function(err,rows){
connection.release();
if(!err) {
res.json(rows);
}
});
connection.on('error', function(err) {
res.json({"code" : 100, "status" : "Error in connection database"});
return;
});
});
}
app.get("/",function(req,res){-
handle_database(req,res);
});
app.listen(3000);
Reference : https://codeforgeek.com/2015/01/nodejs-mysql-tutorial/
KnexJs can be used as an SQL query builder in both Node.JS and the browser.
I find it easy to use. Let try it - Knex.js
$ npm install knex --save
# Then add one of the following (adding a --save) flag:
$ npm install pg
$ npm install sqlite3
$ npm install mysql
$ npm install mysql2
$ npm install mariasql
$ npm install strong-oracle
$ npm install oracle
$ npm install mssql
var knex = require('knex')({
client: 'mysql',
connection: {
host : '127.0.0.1',
user : 'your_database_user',
password : 'your_database_password',
database : 'myapp_test'
}
});
You can use it like this
knex.select('*').from('users')
or
knex('users').where({
first_name: 'Test',
last_name: 'User'
}).select('id')
Imo, you should try MySQL Connector/Node.js which is the official Node.js driver for MySQL.
See ref-1 and ref-2 for detailed explanation.
I have tried mysqljs/mysql which is available here, but I don't find detailed documentation on classes, methods, properties of this library.
So I switched to the standard MySQL Connector/Node.js with X DevAPI, since it is an asynchronous Promise-based client library and provides good documentation.
Take a look at the following code snippet :
const mysqlx = require('#mysql/xdevapi');
const rows = [];
mysqlx.getSession('mysqlx://localhost:33060')
.then(session => {
const table = session.getSchema('testSchema').getTable('testTable');
// The criteria is defined through the expression.
return table.update().where('name = "bar"').set('age', 50)
.execute()
.then(() => {
return table.select().orderBy('name ASC')
.execute(row => rows.push(row));
});
})
.then(() => {
console.log(rows);
});
You can also try out a newer effort known as Node.js DB that aims to provide a common framework for several database engines. It is built with C++ so performance is guaranteed.
Specifically you could use its db-mysql driver for Node.js MySQL support.
connect the mysql database by installing a library. here, picked the stable and easy to use node-mysql module.
npm install mysql#2.0.0-alpha2
var http = require('http'),
mysql = require('mysql');
var sqlInfo = {
host: 'localhost',
user: 'root',
password: 'urpass',
database: 'dbname'
}
client = mysql.createConnection(sqlInfo);
client.connect();
For NodeJS mysql connecting and querying example
You can skip the ORM, builders, etc. and simplify your DB/SQL management using sqler and sqler-mdb.
-- create this file at: db/mdb/setup/create.database.sql
CREATE DATABASE IF NOT EXISTS sqlermysql
const conf = {
"univ": {
"db": {
"mdb": {
"host": "localhost",
"username":"admin",
"password": "mysqlpassword"
}
}
},
"db": {
"dialects": {
"mdb": "sqler-mdb"
},
"connections": [
{
"id": "mdb",
"name": "mdb",
"dir": "db/mdb",
"service": "MySQL",
"dialect": "mdb",
"pool": {},
"driverOptions": {
"connection": {
"multipleStatements": true
}
}
}
]
}
};
// create/initialize manager
const manager = new Manager(conf);
await manager.init();
// .sql file path is path to db function
const result = await manager.db.mdb.setup.create.database();
console.log('Result:', result);
// after we're done using the manager we should close it
process.on('SIGINT', async function sigintDB() {
await manager.close();
console.log('Manager has been closed');
});
I am using Express 4.9.0 and express-generator. Executed this command:
express --hbs projectname
Installed following modules with NPM:
mysql
express-myconnection
I want to make todo application. I have created separate file under routes/todo.js and created get/post routes for creating todos in that file using router.get and router.post.
i have following code in app.js:
// mysql connection
var connection = require('express-myconnection');
var mysql = require('mysql');
app.use(
connection(mysql, {
host : config.db.host,
user : config.db.user,
password : config.db.password,
database : config.db.database,
debug : false //set true if you wanna see debug logger
}, 'request')
);
// end of mysql connection
Where should i place mysql config and connection code? Inside todo.js? I still don't get concept of organisation file structure and where to place database queries.
I don't know if you eventually found the answer, but I thought it might help out others who accidentally stumbled on your question:
After you've setup like mentioned above, you can call the connection from the request object using the getConnection method like this:
exports.index = function(req, res) {
req.getConnection(function (err, connection) {
connection.query('select * from table_name', function(err, rows, fields){
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.jsonp(rows);
}
});
});
};
This should print out a json with the content of your table all nice an pretty.
Hope this comes in handy.