node.jssql-serverdockertedious

NodeJS and SQL Server : unable to connect when in a Docker Container


I have a NodeJS app that works fine when run standalone on a server. When I run it in a docker container it displays the following error message:

ConnectionError: Failed to connect to TEXTREPLACED:undefined - socket hang up

at /app/node_modules/mssql/lib/tedious/connection-pool.js:71:17
at Connection.onConnect (/app/node_modules/tedious/lib/connection.js:1037:9)
at Object.onceWrapper (node:events:514:26)
at Connection.emit (node:events:394:28)
at Connection.emit (/app/node_modules/tedious/lib/connection.js:1065:18)
at Connection.socketError (/app/node_modules/tedious/lib/connection.js:1663:12)
at Connection.socketEnd (/app/node_modules/tedious/lib/connection.js:1693:12)
at Socket. (/app/node_modules/tedious/lib/connection.js:1433:14)
at Socket.emit (node:events:406:35)
at endReadableNT (node:internal/streams/readable:1331:12) {
code: 'ESOCKET',
originalError: ConnectionError: Failed to connect to TEXTREPLACED:undefined - socket hang up
at ConnectionError (/app/node_modules/tedious/lib/errors.js:13:12)
at Connection.socketError (/app/node_modules/tedious/lib/connection.js:1663:56)
at Connection.socketEnd (/app/node_modules/tedious/lib/connection.js:1693:12)
at Socket. (/app/node_modules/tedious/lib/connection.js:1433:14)
at Socket.emit (node:events:406:35)
at endReadableNT (node:internal/streams/readable:1331:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
code: 'ESOCKET'
}
}

My connection code is:

const sqlConfig = {
        user: 'LOGIN',
        password: 'PASSWORD',
        server: 'SERVER\\INSTANCE',
        database: 'DATABASE',
        debug:true,
        port: 1433,
        driver:'tedious',
        pool:{
                idleTimeoutMillis: 1000
        },
        options:{
                port:1433,
                enableArithAbort:true,
                encrypt:true,
                trustServerCertificate:true,
                instanceName:'INSTANCE',
                database:'DATABASE',
                debug:{
                        packet: true,
                        data:true,
                        payload:true,
                        token:true,
                        log:true
                }
        }
};

const global_pool = new sql.ConnectionPool(sqlConfig);
var global_pool_con = null;

try {
        global_pool_con = global_pool.connect();
}catch{
        console.log(err);
}

Dockerfile

# Use Node base image 
FROM node:latest 
#ports 
EXPOSE 3000 
EXPOSE 1433 
WORKDIR /app 
COPY package.json /app 
RUN npm install 
COPY . /app 
USER node
CMD [run, script, release]

The "release" script runs the initial js file.

Confusingly the error shows "undefined" instead of a port number. I have used both host and bridge connections with the ports 1433 and 3000 (HAPI) routed and confirmed the ports are exposed in the dockerfile.

Considering that it works when standalone i'm presuming that a docker setting somewhere it's causing the issue.

Update: The TLS/SSL negotiation packet is being sent but is not received

State change: SentPrelogin -> SentTLSSSLNegotiation

Update: The SQL Server is displaying this error in the event logs when the dockerised app attempts to connect.

A fatal alert was generated and sent to the remote endpoint. This may result in termination of the connection. The TLS protocol defined fatal error code is 40. The Windows SChannel error state is 1205.

An TLS 1.2 connection request was received from a remote client application, but none of the cipher suites supported by the client application are supported by the server. The SSL connection request has failed.

Solution

  • Thanks to everyone for your help.

    The resolution for this was to update the openSSL.cnf file, it had additional lines in it from the source image that weren't required.