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.
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:
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:
@diwakar-s-maurya Thank you for your help! :)
I add HTTP_PROXY, HTTPS_PROXY, FTP_PROXY settings to my Dockerfile and now it works.