Login problems connecting with SQL Server in nodejs - node.js

I'm working in osx with SQL Server using a docker image to be able to use it, running:
docker run -d --name sqlserver -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=myStrongPass' -e 'MSSQL_PID=Developer' -p 1433:1433 microsoft/mssql-server-linux:2017-latest
I can connect successfully in Azure Data Studio GUI with the following configuration
But the connection does not works in my nodejs code using mssql module.
const poolConnection = new sql.ConnectionPool({
database: 'myDbTest',
server: 'localhost',
port: 1433,
password: '*******',
user: 'sa',
connectionTimeout: 5000,
options: {
encrypt: false,
},
});
const [error, connection] = await to(poolConnection.connect());
The error always is the same:
ConnectionError: Login failed for user 'sa'
Is my first time working with SQL Server and is confusing for me the fact that I can connect correctly in the Azure Studio GUI but I can't do it in code.
I'm trying create new login users with CREATE LOGIN and give them privileges based on other post here in stackoverflow but nothing seems to work.
UPDATE:
I realize that i can connect correctly if i put master in database key.
Example:
const poolConnection = new sql.ConnectionPool({
database: 'master', <- Update here
server: 'localhost',
port: 1433,
password: '*******',
user: 'sa',
connectionTimeout: 5000,
options: {
encrypt: false,
},
});
1) Db that i can connect
2) Db that i want to connect but i can't.
Container error
2020-03-18 03:59:14.11 Logon Login failed for user 'sa'. Reason: Failed to open the explicitly specified database 'DoctorHoyCRM'. [CLIENT: 172.17.0.1]

I suspect a lot of people miss the sa password complexity requirement:
The password should follow the SQL Server default password policy, otherwise the container can not setup SQL server and will stop working. By default, the password must be at least 8 characters long and contain characters from three of the following four sets: Uppercase letters, Lowercase letters, Base 10 digits, and Symbols. You can examine the error log by executing the docker logs command.
An example based on: Quickstart: Run SQL Server container images with Docker
docker pull mcr.microsoft.com/mssql/server:2017-latest
docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=myStr0ngP4ssw0rd" -e "MSSQL_PID=Developer" -p 1433:1433 --name sqlserver -d mcr.microsoft.com/mssql/server:2017-latest
docker start sqlserver
Checking that the docker image is running (it should not say "Exited" under STATUS)...
docker ps -a
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# af9f01eacab2 mcr.microsoft.com/mssql/server:2017-latest "/opt/mssql/bin/nonr…" 45 seconds ago Up 34 seconds 0.0.0.0:1433->1433/tcp sqlserver
Testing from within the docker container that SQL Server is installed and running...
docker exec -it sqlserver /opt/mssql-tools/bin/sqlcmd \
-S localhost -U "sa" -P "myStr0ngP4ssw0rd" \
-Q "select ##VERSION"
# --------------------------------------------------------------------
# Microsoft SQL Server 2017 (RTM-CU19) (KB4535007) - 14.0.3281.6 (X64)
# Jan 23 2020 21:00:04
# Copyright (C) 2017 Microsoft Corporation
# Developer Edition (64-bit) on Linux (Ubuntu 16.04.6 LTS)
Finally, testing from NodeJS...
const sql = require('mssql');
const config = {
user: 'sa',
password: 'myStr0ngP4ssw0rd',
server: 'localhost',
database: 'msdb',
};
sql.on('error', err => {
console.error('err: ', err);
});
sql.connect(config).then(pool => {
return pool.request()
.query('select ##VERSION')
}).then(result => {
console.dir(result)
}).catch(err => {
console.error('err: ', err);
});
$ node test.js
tedious deprecated The default value for `config.options.enableArithAbort` will change from `false` to `true` in the next major version of `tedious`. Set the value to `true` or `false` explicitly to silence this message. node_modules/mssql/lib/tedious/connection-pool.js:61:23
{
recordsets: [ [ [Object] ] ],
recordset: [
{
'': 'Microsoft SQL Server 2017 (RTM-CU19) (KB4535007) - 14.0.3281.6 (X64) \n' +
'\tJan 23 2020 21:00:04 \n' +
'\tCopyright (C) 2017 Microsoft Corporation\n' +
'\tDeveloper Edition (64-bit) on Linux (Ubuntu 16.04.6 LTS)'
}
],
output: {},
rowsAffected: [ 1 ]
}
Hope this helps.

Related

I am unable to connect Mongodb atlas Cluster from node js getting following unable to connect DB error

{ error: 1, message: 'Command failed: mongodump -h cluster0.yckk6.mongodb.net --port=27017 -d databaseName -p -u --gzip --archive=/tmp/file_name_2022-09-19T09-42-05.gz\n' + '2022-09-19T14:42:08.931+0000\tFailed: error connecting to db server: no reachable servers\n' }
Can anyone help me to solve this problem and following is my backup code
function databaseBackup() {
let backupConfig = {
mongodb: "mongodb+srv://<username>:<password>#cluster0.yckk6.mongodb.net:27017/databaseName?
retryWrites=true&w=majority&authMechanism=SCRAM-SHA-1", // MongoDB Connection URI
s3: {
accessKey: "SDETGGAKIA2GL", //AccessKey
secretKey: "Asad23rdfdg2teE8lOS3JWgdfgfdgfg", //SecretKey
region: "ap-south-1", //S3 Bucket Region
accessPerm: "private", //S3 Bucket Privacy, Since, You'll be storing Database, Private is HIGHLY Recommended
bucketName: "backupDatabase" //Bucket Name
},
keepLocalBackups: false, //If true, It'll create a folder in project root with database's name and store backups in it and if it's false, It'll use temporary directory of OS
noOfLocalBackups: 5, //This will only keep the most recent 5 backups and delete all older backups from local backup directory
timezoneOffset: 300 //Timezone, It is assumed to be in hours if less than 16 and in minutes otherwise
}
MBackup(backupConfig).then(onResolve => {
// When everything was successful
console.log(onResolve);
}).catch(onReject => {
// When Anything goes wrong!
console.log(onReject);
});
}

Jest detects open redis client on travis-ci

I encountered some difficulties with redis testing on travis-ci.
Here is the redis setup code,
async function getClient() {
const redisClient = createClient({
socket: {
url: redisConfig.connectionString,
reconnectStrategy: (currentNumberOfRetries: number) => {
if (currentNumberOfRetries > 1) {
throw new Error("max retries reached");
}
return 1000;
},
},
});
try {
await redisClient.connect();
} catch (e) {
console.log(e);
}
return redisClient;
}
Here is the travis config, note that I run npm install redis because it is listed as a peer dependency.
language: node_js
node_js:
- "14"
dist: focal # ubuntu 20.04
services:
- postgresql
- redis-server
addons:
postgresql: "13"
apt:
packages:
- postgresql-13
env:
global:
- PGUSER=postgres
- PGPORT=5432 # for some reason unlike what documentation says, the port is 5432
jobs:
- NODE_ENV=ci
cache:
directories:
- node_modules
before_install:
- sudo sed -i -e '/local.*peer/s/postgres/all/' -e 's/peer\|md5/trust/g' /etc/postgresql/*/main/pg_hba.conf
- sudo service postgresql restart
- sleep 1
- postgres --version
- pg_lsclusters # shows port of postgresql, ubuntu specific command
install:
- npm i
- npm i redis
before_script:
- sudo psql -c 'create database orm_test;' -p 5432 -U postgres
script:
- npm run test-detectopen
The first issue is this missing client.connect function, whereas connection on my local machine with redis-server running works.
console.log
TypeError: redisClient.connect is not a function
at Object.getClient (/home/travis/build/sunjc826/mini-orm/src/connection/redis/index.ts:21:23)
at Function.init (/home/travis/build/sunjc826/mini-orm/src/data-mapper/index.ts:33:30)
at /home/travis/build/sunjc826/mini-orm/src/lib-test/tests/orm.test.ts:25:20
at Promise.then.completed (/home/travis/build/sunjc826/mini-orm/node_modules/jest-circus/build/utils.js:390:28)
at new Promise (<anonymous>)
at callAsyncCircusFn (/home/travis/build/sunjc826/mini-orm/node_modules/jest-circus/build/utils.js:315:10)
at _callCircusHook (/home/travis/build/sunjc826/mini-orm/node_modules/jest-circus/build/run.js:181:40)
at _runTestsForDescribeBlock (/home/travis/build/sunjc826/mini-orm/node_modules/jest-circus/build/run.js:47:7)
at run (/home/travis/build/sunjc826/mini-orm/node_modules/jest-circus/build/run.js:25:3)
at runAndTransformResultsToJestFormat (/home/travis/build/sunjc826/mini-orm/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:166:21)
The second is this open handle issue, on my local machine, even if connection fails, jest does not give such an error and exits cleanly.
Jest has detected the following 1 open handle potentially keeping Jest from exiting:
● TCPWRAP
7 |
8 | async function getClient() {
> 9 | const redisClient = createClient({
| ^
10 | socket: {
11 | url: redisConfig.connectionString,
12 | reconnectStrategy: (currentNumberOfRetries: number) => {
at RedisClient.Object.<anonymous>.RedisClient.create_stream (node_modules/redis/index.js:196:31)
at new RedisClient (node_modules/redis/index.js:121:10)
at Object.<anonymous>.exports.createClient (node_modules/redis/index.js:1023:12)
at Object.getClient (src/connection/redis/index.ts:9:23)
at Function.init (src/data-mapper/index.ts:33:30)
at src/lib-test/tests/orm.test.ts:25:20
at TestScheduler.scheduleTests (node_modules/#jest/core/build/TestScheduler.js:333:13)
at runJest (node_modules/#jest/core/build/runJest.js:387:19)
at _run10000 (node_modules/#jest/core/build/cli/index.js:408:7)
at runCLI (node_modules/#jest/core/build/cli/index.js:261:3)
It turns out that this is likely caused by redis being a peer dependency.
Listing out node-redis versions, I'm guessing the version tagged latest (as of time writing 3.1.2) was installed instead of the version 4+.
So, I moved redis to regular dependencies instead.

NestJS and TypeORM fail to connect my local Postgres database. Claims my database does not exist, even tho it does

I have NestJS application that uses TypeORM to connect to my local database. I create database with shell script:
#!/bin/bash
set -e
SERVER="my_database_server";
PW="mysecretpassword";
DB="my_database";
echo "echo stop & remove old docker [$SERVER] and starting new fresh instance of [$SERVER]"
(docker kill $SERVER || :) && \
(docker rm $SERVER || :) && \
docker run --name $SERVER -e POSTGRES_PASSWORD=$PW \
-e PGPASSWORD=$PW \
-p 5432:5432 \
-d postgres
# wait for pg to start
echo "sleep wait for pg-server [$SERVER] to start";
SLEEP 3;
# create the db
echo "CREATE DATABASE $DB ENCODING 'UTF-8';" | docker exec -i $SERVER psql -U postgres
echo "\l" | docker exec -i $SERVER psql -U postgres
After that, it logs databases:
Then I fire up my application, and I encounter error "error: database "my_database" does not exist"
I use following code to connect to database:
static getDatabaseConnection(): TypeOrmModuleOptions {
console.log(require('dotenv').config())
return {
type: 'postgres',
host: "127.0.0.1",
port: 5432,
username: 'postgres',
password: 'mysecretpassword',
database: 'my_database',
entities: ['dist/**/*.entity{.ts,.js}'],
synchronize: true,
};
}
Any ideas where do I go wrong?
When connecting to a docker instance, you should usually use the service name. In this case I guess it is my_database_server as host parameter.
return {
type: 'postgres',
host: "my_database_server",
port: 5432,
username: 'postgres',
password: 'mysecretpassword',
database: 'my_database',
entities: ['dist/**/*.entity{.ts,.js}'],
synchronize: true,
};
"localhost" isn't address of your docker container. Which address uses docker you can look running command:
$ docker inspect {your_container_name}
for me is: 172.17.0.2
Try enable SSL, adding next configuration lines:
ssl: true,
extra: { ssl: { rejectUnauthorized: false } }
Try using localhost instead of 127.0.0.1

docker -minio - The access key ID you provided does not exist in our records

I have a docker file that should wait for a database with wait_for_it.sh and run a minio server.
I read the secrets from run/secrets and creates the MINIO_SECRET_KEY and MINIO_ACCESS_KEY.
THE MINIO SERVER is up but I cannot connect with a minio client (js client) and I GOT the following error:
The access key ID you provided does not exist in our records
My client code:
const accessKey = fileService.readFile(configService.get('minio').access_key_file);
const secretKey = fileService.readFile(configService.get('minio').secret_key_file);
this.minioClient = new Minio.Client({
endPoint: configService.get('minio').host,
port: configService.get('minio').port,
useSSL: configService.get('minio').useSSL,
accessKey: accessKey.trim(),
secretKey: secretKey.trim()
});
my docker entry point (bash):
docker_secrets_env() {
ACCESS_KEY_FILE="$MINIO_ACCESS_KEY_FILE"
SECRET_KEY_FILE="$MINIO_SECRET_KEY_FILE"
if [ -f "$ACCESS_KEY_FILE" ] && [ -f "$SECRET_KEY_FILE" ]; then
if [ -f "$ACCESS_KEY_FILE" ]; then
MINIO_ACCESS_KEY="$(cat "$ACCESS_KEY_FILE")"
export MINIO_ACCESS_KEY
fi
if [ -f "$SECRET_KEY_FILE" ]; then
MINIO_SECRET_KEY="$(cat "$SECRET_KEY_FILE")"
export MINIO_SECRET_KEY
fi
fi
}
docker_secrets_env
./wait-for-it.sh mongo:27017 --timeout=0 --strict -- \
minio server /data & \
thanks
Try to access it directly at localhost:9000 with your preset credentials,
if that doesn't work try default credentials :
user: minioadmin
PWD: minioadmin
if this works it means the docker image wasn't run properly.

Docker - SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:3306

I'm trying to get my nodejs application up and running using a docker container. I have no clue what might be wrong. The credentials seems to be passed correctly when I debug the credentials with the console. Also firing up sequel pro and connecting directly with the same username and password seems to work. When node starts in the container I get the error message:
SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:3306
The application itself is loading correctly on port 3000, however no data is retrieved from the database. If have also tried adding the environment variables directly to the docker compose file, but this also doesn't seem to work.
My project code is hosted over here: https://github.com/pietheinstrengholt/rssmonster
The following database.js configuration is used. When I add console.log(config) the correct credentials from the .env file are displayed.
require('dotenv').load();
const Sequelize = require('sequelize');
const fs = require('fs');
const path = require('path');
const env = process.env.NODE_ENV || 'development';
const config = require(path.join(__dirname + '/../config/config.js'))[env];
if (config.use_env_variable) {
var sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
var sequelize = new Sequelize(config.database, config.username, config.password, config);
}
module.exports = sequelize;
When I do a console.log(config) inside the database.js I get the following output:
{
username: 'rssmonster',
password: 'password',
database: 'rssmonster',
host: 'localhost',
dialect: 'mysql'
}
Following .env:
DB_HOSTNAME=localhost
DB_PORT=3306
DB_DATABASE=rssmonster
DB_USERNAME=rssmonster
DB_PASSWORD=password
And the following docker-compose.yml:
version: '2.3'
services:
app:
depends_on:
mysql:
condition: service_healthy
build:
context: ./
dockerfile: app.dockerfile
image: rssmonster/app
ports:
- 3000:3000
environment:
NODE_ENV: development
PORT: 3000
DB_USERNAME: rssmonster
DB_PASSWORD: password
DB_DATABASE: rssmonster
DB_HOSTNAME: localhost
working_dir: /usr/local/rssmonster/server
env_file:
- ./server/.env
links:
- mysql:mysql
mysql:
container_name: mysqldb
image: mysql:5.7
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
MYSQL_DATABASE: "rssmonster"
MYSQL_USER: "rssmonster"
MYSQL_PASSWORD: "password"
ports:
- "3307:3306"
volumes:
- /var/lib/mysql
restart: unless-stopped
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
timeout: 5s
retries: 10
volumes:
dbdata:
Error output:
{ SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:3306
app_1 | at Promise.tap.then.catch.err (/usr/local/rssmonster/server/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:128:19)
app_1 | From previous event:
app_1 | at ConnectionManager.connect (/usr/local/rssmonster/server/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:125:13)
app_1 | at sequelize.runHooks.then (/usr/local/rssmonster/server/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:306:50)
app_1 | From previous event:
app_1 | at ConnectionManager._connect (/usr/local/rssmonster/server/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:306:8)
app_1 | at ConnectionManager.getConnection (/usr/local/rssmonster/server/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:247:46)
app_1 | at Promise.try (/usr/local/rssmonster/server/node_modules/sequelize/lib/sequelize.js:564:34)
app_1 | From previous event:
app_1 | at Promise.resolve.retryParameters (/usr/local/rssmonster/server/node_modules/sequelize/lib/sequelize.js:464:64)
app_1 | at /usr/local/rssmonster/server/node_modules/retry-as-promised/index.js:60:21
app_1 | at new Promise (<anonymous>)
Insteaf of localhost point to mysql which is the service name (DNS) that nodejs will resolve into the MySQL container:
DB_HOSTNAME: mysql
And
{
...
host: 'mysql',
...
}
Inside of the container you should reference the container by the name you gave in your docker-compose.yml file.
In this case you should use
DB_HOSTNAME: mysql
After searching and digging up through several googling attempt, the culprit of the problem soon appear. In this context, the database server is not in the same machine. In other words, the MySQL Database Server address is not localhost. So, how can the above MySQL database configuration by default is pointing to localhost address. Well, it seems that if there is no further definition of the host address, it will connect to the localhost address by default. Read the article for further reference about sequelize syntax pattern in this link.
So, in order to solve the problem, just modify the file with the right configuration database. The following is the correction of the configuration database :
const sequelize = require("sequelize")
const db = new sequelize("db_master","db_user","password", {
host : "10.0.2.2",
dialect: "mysql"
});
db.sync({});
module.exports = db;
Actually, the NodeJS application is running in a virtual server. It is a guest machine run in a VirtualBox application. On the other hand, MySQL Database server exist outside the guest machine. It is available in the host machine where the VirtualBox application is running. The host machine IP address is 10.0.2.2. So, in order to connect to MySQL Database Server in the host machine, the IP address of the host is 10.0.2.2.
use your connection string as :
mysql://username:password#mysql:(port_running_on_container)or(exposed_port)/db_name
Answers already exist, but to provide some further explanation:
You can't use 127.0.0.1 (localhost) to access other services/containers since each container will view that as inside itself. When running docker-compose, all your services will be entered into the same docker network. All services inside the same docker network, are able to reach eachother by service name.
hence, as already stated in previous answers: in your configuration, change db hostname from localhost to mysql.
three things to check before
make sure your service name must be MySQL
in Configure DB_HOST also a MySQL
And your backend service depends on mysql in docker-compose.yml
here is my success code
export const db = new Sequelize(
process.env.DB_NAME,
process.env.DB_USER,
process.env.DB_PASSWORD,
{
port: process.env.DB_PORT,
host:'mysql',
dialect: "mysql",
logging: false,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
}
);

Resources