Node-oracledb: Error: NJS-045: cannot load the oracledb add-on binary for Node.js

Created on 28 Dec 2018  路  13Comments  路  Source: oracle/node-oracledb

In my Node.JS project I use node-oracledb package which connect to remote ORACLE database. I developed that project in Windows 10 OS and it works fine. Now in production server (CentOS) I created Docker Image by next Dockerfile:

FROM node:latest
COPY / ./
EXPOSE 3001
CMD ["sqlplus", "-v", "npm", "start"]

It create Docker Image without any error. Then I create Docker Container but unfortunatly in logs I notice this error:

/src/node_modules/oracledb/lib/oracledb.js:68
      throw new Error(nodbUtil.getErrorMessage('NJS-045', nodeInfo));
      ^

Error: NJS-045: cannot load the oracledb add-on binary for Node.js 8.12.0 (linux, x64)
Cannot load /src/node_modules/oracledb/build/Release/oracledb.node
/src/node_modules/oracledb/build/Release/oracledb.node: invalid ELF header
Node-oracledb installation instructions: https://oracle.github.io/node-oracledb/INSTALL.html
You must have 64-bit Oracle client libraries in LD_LIBRARY_PATH, or configured with ldconfig.
If you do not have Oracle Database on this computer, then install the Instant Client Basic or Basic Light package from
http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html

    at Object.<anonymous> (/src/node_modules/oracledb/lib/oracledb.js:68:13)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/src/node_modules/oracledb/index.js:1:80)
    at Module._compile (module.js:653:30)

How to fix this problem?

I use instruction from official documentation to install oracle instant client and set environment variable (LD_LIBRARY_PATH). Unfortunatly the error is steal the same.

install & configuration

All 13 comments

You need to package the correct node-oracledb for Linux. It's possible you have the one for Windows in your container which is why you are getting the invalid ELF header error.

@cjbj Thank you for your answer. I tried to change Dockerfile where I rebuild node-oracledb package as you adviced.

Unfortunatly it raise new error:

/node_modules/oracledb/lib/oracledb.js:65
      throw new Error(nodbUtil.getErrorMessage('NJS-045', nodeInfo));
      ^

Error: NJS-045: cannot load the oracledb add-on binary for Node.js 11.4.0 (linux, x64)
Node.js require() error was:
  DPI-1047: 64-bit Oracle Client library cannot be loaded: "libclntsh.so: cannot open shared object file: No such file or directory". See https://oracle.github.io/odpi/doc/installation.html#linux for help
Node.js require() mapped to /node_modules/oracledb/build/Release/oracledb.node
Node-oracledb installation instructions: https://oracle.github.io/node-oracledb/INSTALL.html
You must have 64-bit Oracle client libraries in LD_LIBRARY_PATH, or configured with ldconfig.
If you do not have Oracle Database on this computer, then install the Instant Client Basic or Basic Light package from
http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html

    at Object.<anonymous> (/node_modules/oracledb/lib/oracledb.js:65:13)
    at Module._compile (internal/modules/cjs/loader.js:723:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:734:10)
    at Module.load (internal/modules/cjs/loader.js:620:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
    at Function.Module._load (internal/modules/cjs/loader.js:552:3)
    at Module.require (internal/modules/cjs/loader.js:659:17)
    at require (internal/modules/cjs/helpers.js:22:18)
    at Object.<anonymous> (/node_modules/oracledb/index.js:1:80)
    at Module._compile (internal/modules/cjs/loader.js:723:30)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `node index.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2018-12-28T12_06_50_714Z-debug.log

Is it mean that I also need to install Oracle Instant Client to Docker? So confused. I install it to CentOS.

@cjbj with next Dockerfile I create image successfully. Next code install Oracle Instant Client to Docker. Unfortunatly error the same. Do you have any ideas? What kind of settings I must to make with libclntsh.so?

FROM oraclelinux:7-slim

RUN  curl -o /etc/yum.repos.d/public-yum-ol7.repo https://yum.oracle.com/public-yum-ol7.repo && \
     yum-config-manager --enable ol7_oracle_instantclient && \
     yum -y install oracle-instantclient18.3-basic oracle-instantclient18.3-devel oracle-instantclient18.3-sqlplus && \
     rm -rf /var/cache/yum && \
     echo /usr/lib/oracle/18.3/client64/lib > /etc/ld.so.conf.d/oracle-instantclient18.3.conf && \
     ldconfig

ENV PATH=$PATH:/usr/lib/oracle/18.3/client64/bin

FROM node:latest

COPY / ./

EXPOSE 3001

RUN npm rebuild oracledb

CMD ["npm", "start"]

@NogerbekNurzhan Can you share the exact Dockerfile?

@diwakar-s-maurya can you check my previous comment please? I add Dockerfile in that comment. It seems like I miss something. Do you have any ideas?

@NogerbekNurzhan Try this Dockerfile

FROM node:8

WORKDIR /usr/app

# start: oracle client libs setups
RUN apt-get update \
    && apt-get install -y libaio1 build-essential unzip curl vim
COPY ./dependencies/oracle/instantclient-basic-linux.x64-12.2.0.1.0.zip .
COPY ./dependencies/oracle/instantclient-sdk-linux.x64-12.2.0.1.0.zip .
COPY ./dependencies/oracle/instantclient-sqlplus-linux.x64-12.2.0.1.0.zip .
RUN unzip -qq instantclient-basic-linux.x64-12.2.0.1.0.zip -d /opt/oracle
RUN unzip -qq instantclient-sdk-linux.x64-12.2.0.1.0.zip -d /opt/oracle
RUN unzip -qq instantclient-sqlplus-linux.x64-12.2.0.1.0.zip -d /opt/oracle
RUN mkdir -p /opt/oracle/instantclient_12_2/bin
RUN mv /opt/oracle/instantclient_12_2/sqlplus /opt/oracle/instantclient_12_2/bin
RUN echo /opt/oracle/instantclient_12_2 > /etc/ld.so.conf.d/oracle-instantclient.conf
ENV LD_LIBRARY_PATH=/opt/oracle/instantclient_12_2:$LD_LIBRARY_PATH
ENV ORACLE_HOME=/opt/oracle/instantclient_12_2
ENV PATH=$PATH:$ORACLE_HOME/bin
# done: oracle client libs setups

COPY package.json ./
RUN npm install

# copy your code
COPY ./connection_test.js ./

# Start
CMD [ "node", "/usr/app/connection_test.js" ]

Before building, download the Oracle dependencies from https://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html and place in ./dependencies/oracle

I am guessing that somehow node_modules that are not compatible in node:latest are landing in the image while building it. Add node_modules in .dockerignore file to make sure that it does not.

In the original Dockerfile that you tried,

FROM node:latest
COPY / ./
EXPOSE 3001
CMD ["sqlplus", "-v", "npm", "start"]

did you run npm install && build the docker image on the windows or centos/debian?

@diwakar-s-maurya let me try to explain you everything step by step.

1) I developed that project in Windows 10 (local computer) and it works fine.
2) Then I put that project to remote production CentOS server which has Docker. By the way project has _node_modules_ folder.
3) At start my Dockerfile was like this:

FROM node:latest
COPY / ./
EXPOSE 3001
CMD ["npm", "start"]

I create image successfully but I had next errors in logs:

Error: NJS-045: cannot load the oracledb add-on binary for Node.js 8.12.0 (linux, x64)
Cannot load /src/node_modules/oracledb/build/Release/oracledb.node
/src/node_modules/oracledb/build/Release/oracledb.node: invalid ELF header
Node-oracledb installation instructions: https://oracle.github.io/node-oracledb/INSTALL.html
You must have 64-bit Oracle client libraries in LD_LIBRARY_PATH, or configured with ldconfig.
If you do not have Oracle Database on this computer, then install the Instant Client Basic or Basic Light package from
http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html

@cjbj adviced to me to install node-oracledb for Linux cause problem was with invalid ELF header.

4) After his advice, I change my Dockerfile to this:

FROM node:latest
COPY / ./
EXPOSE 3001
RUN npm rebuild oracledb
CMD ["npm", "start"]

With next Dockerfile I had errors in logs which about Oracle Instant Client:

Error: NJS-045: cannot load the oracledb add-on binary for Node.js 11.4.0 (linux, x64)
Node.js require() error was:
  DPI-1047: 64-bit Oracle Client library cannot be loaded: "libclntsh.so: cannot open shared object file: No such file or directory". See https://oracle.github.io/odpi/doc/installation.html#linux for help
Node.js require() mapped to /node_modules/oracledb/build/Release/oracledb.node
Node-oracledb installation instructions: https://oracle.github.io/node-oracledb/INSTALL.html
You must have 64-bit Oracle client libraries in LD_LIBRARY_PATH, or configured with ldconfig.
If you do not have Oracle Database on this computer, then install the Instant Client Basic or Basic Light package from
http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html

5) So finally I use next Dockerfile which install Oracle Instant Client to Docker but the error in logs was the same as in step 4.

FROM oraclelinux:7-slim

RUN  curl -o /etc/yum.repos.d/public-yum-ol7.repo https://yum.oracle.com/public-yum-ol7.repo && \
     yum-config-manager --enable ol7_oracle_instantclient && \
     yum -y install oracle-instantclient18.3-basic oracle-instantclient18.3-devel oracle-instantclient18.3-sqlplus && \
     rm -rf /var/cache/yum && \
     echo /usr/lib/oracle/18.3/client64/lib > /etc/ld.so.conf.d/oracle-instantclient18.3.conf && \
     ldconfig

ENV PATH=$PATH:/usr/lib/oracle/18.3/client64/bin

FROM node:latest
COPY / ./
EXPOSE 3001
RUN npm rebuild oracledb
CMD ["npm", "start"]

I think the problem is because of uploading node_modules along with the code from windows to centos server and then building the container image. The node_modules are entering the image along the code when you do COPY / ./ Don't use the node_modules of windows. It is not compatible with node:8.

@diwakar-s-maurya if I understand you correct I need to remove node_modules folder from my project in CentOS server or add that folder to .dockerignore. Right?

I download 3 instantclient .zip file and put them inside this folder:
/home/nurzhan_nogerbek/saturn-backend/dependencies/oracle/

Directory where are all my code (package.json, index.js, node_modules...):
/home/nurzhan_nogerbek/saturn-backend

Dockerfile in the same level as package.json file. In other words it is inside this folder:
/home/nurzhan_nogerbek/saturn-backend

I remove node_modules folder and tried to create image by next Dockerfile:

FROM node:8

WORKDIR /home/nurzhan_nogerbek/saturn-backend

RUN apt-get update && apt-get install -y libaio1 build-essential unzip curl vim

COPY ./dependencies/oracle/instantclient-basic-linux.x64-12.2.0.1.0.zip .
COPY ./dependencies/oracle/instantclient-sdk-linux.x64-12.2.0.1.0.zip .
COPY ./dependencies/oracle/instantclient-sqlplus-linux.x64-12.2.0.1.0.zip .

RUN unzip -qq instantclient-basic-linux.x64-12.2.0.1.0.zip -d /opt/oracle
RUN unzip -qq instantclient-sdk-linux.x64-12.2.0.1.0.zip -d /opt/oracle
RUN unzip -qq instantclient-sqlplus-linux.x64-12.2.0.1.0.zip -d /opt/oracle

RUN mkdir -p /opt/oracle/instantclient_12_2/bin
RUN mv /opt/oracle/instantclient_12_2/sqlplus /opt/oracle/instantclient_12_2/bin
RUN echo /opt/oracle/instantclient_12_2 > /etc/ld.so.conf.d/oracle-instantclient.conf
ENV LD_LIBRARY_PATH=/opt/oracle/instantclient_12_2:$LD_LIBRARY_PATH
ENV ORACLE_HOME=/opt/oracle/instantclient_12_2
ENV PATH=$PATH:$ORACLE_HOME/bin

COPY / ./

RUN npm install

EXPOSE 3001

CMD ["npm", "start"]

I have error when try to install:
default

Do you have any ideas about that?

The error is because of the connection being blocked to download the packages. There might be restrictions put on the CentOS server on which you are trying to run it. I have tested this Dockerfile. It worked for me.

A few things about the Dockerfile:

  • you don't need to set LD_LIBRARY_PATH since you configure ldconfig
  • with Instant Client you should not set ORACLE_HOME
  • use 18.3 (which is the renumbered 12.2.0.2) instead of 12.2
  • you mention CentOS but the dockerfile looks like it is for Ubuntu
  • If you are on system that uses RPMs, install the Instant Client RPMs - this is easy now the 18.3 RPMs are available from http://yum.oracle.com/repo/OracleLinux/OL7/oracle/instantclient/x86_64/index.html without needing login or a clickthrough
  • since you are running in a container, there's no reason not to use Oracle Linux. Start with this Dockerfile https://github.com/oracle/docker-images/blob/master/OracleInstantClient/dockerfiles/18.3.0/Dockerfile (as you had above) and add Node.js to it. Work with one configuration and don't jump around - it makes it hard to advise you.
  • depending on which Node.js binary you want, you could consider the RPMs from http://yum.oracle.com/oracle-linux-nodejs.html
  • do you need to set a proxy in the container so it can install node-oracledb?
  • If installing node-oracledb is difficult because of network issues or because of you are using Windows to build the container, then do a manual extraction of the Linux node-oracledb binary and copy it to the image.

@diwakar-s-maurya Thank you for your help! :)

I add HTTP_PROXY, HTTPS_PROXY, FTP_PROXY settings to my Dockerfile and now it works.

Was this page helpful?
0 / 5 - 0 ratings