mattn / go-oci8

Oracle driver for Go using database/sql
https://mattn.kaoriya.net/
MIT License
630 stars 212 forks source link

problem building docker + go-oci8 #347

Closed fabulias closed 4 years ago

fabulias commented 5 years ago

Hi, I'm trying to build a container and I can't advance more than a step, I think that I have everything but my docker insists on failing. In my computer I have the following files:

my_project/oracle/instantclient (instant_client version 18.1)
my_project/oracle/oci8.pc

EDIT: I'm using windows 10.

I have the following Dockerfile and oci8.pc files.

prefix=/opt/instantclient
libdir=${prefix}
includedir=${prefix}/sdk/include/

Name: OCI
Description: oci8 library
Libs: -L${libdir} -lclntsh
Cflags: -I${includedir}
Version: 18.1
FROM golang:1.12.7

RUN apt-get update
RUN apt-get install -y pkg-config && \
    apt-get install -y libaio1 

ENV CLIENT_FILENAME instantclient
COPY /oracle/${CLIENT_FILENAME} /opt/instantclient
COPY /oracle/oci8.pc /usr/lib/pkgconfig/oci8.pc

ENV LD_LIBRARY_PATH /usr/lib:/usr/local/lib:/opt/instantclient

RUN go get -u github.com/mattn/go-oci8

The error is:

Step 8/8 : RUN go get -u github.com/mattn/go-oci8
 ---> Running in 0c0a61c9d52e
# github.com/mattn/go-oci8
/usr/bin/ld: cannot find -lclntsh
collect2: error: ld returned 1 exit status
The command '/bin/sh -c go get -u github.com/mattn/go-oci8' returned a non-zero code: 2

I don't know why I have problems with this line if I create my Dockerfile from https://github.com/jeanmorais/docker-go-oci8 and jeanmorais doesn't import another library.

MichaelS11 commented 5 years ago

In the vm / dockerfile, maybe try running pkg-config and check the output? pkg-config oci8

cjbj commented 5 years ago

Better not to set LD_LIBRARY_PATH. Just use ldconfig like https://github.com/oracle/docker-images/blob/master/OracleInstantClient/dockerfiles/18/Dockerfile#L25-L26

Or use Instant Client 19c RPMs and you don't even need to manually set any library path: https://github.com/oracle/docker-images/blob/master/OracleInstantClient/dockerfiles/19/Dockerfile#L20-L21

fabulias commented 5 years ago

In the vm / dockerfile, maybe try running pkg-config and check the output? pkg-config oci8

Nothing :/

Step 8/9 : RUN pkg-config oci8
 ---> Running in 251e6f311e6f
Removing intermediate container 251e6f311e6f
 ---> 796edd00bf79

Or use Instant Client 19c RPMs and you don't even need to manually set any library path: https://github.com/oracle/docker-images/blob/master/OracleInstantClient/dockerfiles/19/Dockerfile#L20-L21

I will try it.

MichaelS11 commented 5 years ago

Also did you set ORACLE_HOME and TNS_ADMIN?

Instead of setting LD_LIBRARY_PATH can setup a ld config file. (Change to the correct path)

echo '/opt/instantclient/18.1/client64/lib' > /etc/ld.so.conf.d/oracle-18.conf
ldconfig
cjbj commented 5 years ago

Unless some old install script needs it, never set ORACLE_HOME when you are using Instant Client.

MichaelS11 commented 5 years ago

@cjbj Why never set ORACLE_HOME? Are you saying just for new versions of Oracle Instant Client?

cjbj commented 5 years ago

This has always been true. It's unnecessary and confusing for users to set ORACLE_HOME for Instant Client. Internally IC sets ORACLE_HOME so that Oracle code layers that dereference it will still work.

fabulias commented 5 years ago

@cjbj After try it, I don't obtain good results.

Step 8/8 : RUN go get -u github.com/mattn/go-oci8
 ---> Running in bbe906ca215b
# github.com/mattn/go-oci8
In file included from src/github.com/mattn/go-oci8/cHelpers.go:3:
./oci8.go.h:1:10: fatal error: oci.h: No such file or directory
 #include <oci.h>
          ^~~~~~~
compilation terminated.
The command '/bin/sh -c go get -u github.com/mattn/go-oci8' returned a non-zero code: 2

This is my new Dockerfile

FROM golang:1.12.7

RUN apt-get update
RUN apt-get install -y pkg-config && \
    apt-get install -y libaio1 

ENV CLIENT_FILENAME instantclient_19_3
COPY /oracle/${CLIENT_FILENAME} /opt/instantclient
COPY /oracle/oci8.pc /usr/lib/pkgconfig/oci8.pc

# ENV LD_LIBRARY_PATH /usr/lib:/usr/local/lib:/opt/instantclient
RUN go get -u github.com/mattn/go-oci8

I also try without comment ENV LD_LIBRARY_PATH line and the result is the same.

MichaelS11 commented 5 years ago

Could you try pkg-config --print-errors --debug before the go get and see what the output is?

Also did you try the suggestion above about ldconfig?

fabulias commented 5 years ago

Also did you set ORACLE_HOME and TNS_ADMIN?

Instead of setting LD_LIBRARY_PATH can setup a ld config file. (Change to the correct path)

echo '/opt/instantclient/18.1/client64/lib' > /etc/ld.so.conf.d/oracle-18.conf
ldconfig

But I don't have some folder called client64 or something seems to it.

Please, look at my folder structure if you want to check.

treeInstantClient18_3

Could you try pkg-config --print-errors --debug before the go get and see what the output is?

Also did you try the suggestion above about ldconfig?

I modify my Dockerfile before test this, but in general is the same (I added PKG_CONFIG_PATH variable)

FROM golang:1.12.7

RUN apt-get update
RUN apt-get install -y pkg-config && \
    apt-get install -y libaio1 && \
    apt-get install unzip

ENV CLIENT_FILENAME instantclient_18_3.zip
COPY /oracle/${CLIENT_FILENAME} .
COPY /oracle/oci8.pc /usr/lib/pkgconfig/oci8.pc

ENV PKG_CONFIG_PATH /usr/lib/pkgconfig
RUN ls -lha /usr/lib/pkgconfig
ENV LD_LIBRARY_PATH /usr/lib:/usr/local/lib:/usr/instantclient_18_3
# to build the application with mattn/go-oci8, it is necessary to extract all files, including the SDK.
RUN unzip ${CLIENT_FILENAME} -d /usr
RUN ls -lha /usr &&  \
    ln -s /usr/instantclient/libclntsh.so.18.1 /usr/instantclient/libclntsh.so && \
    ln -s /usr/instantclient/libclntshcore.so.18.1 /usr/instantclient/libclntshcore.so && \
    ln -s /usr/instantclient/libocci.so.18.1 /usr/instantclient/libocci.so

RUN pkg-config --print-errors --debug
RUN go get -u github.com/mattn/go-oci8

And the error is :

Step 12/13 : RUN pkg-config --print-errors --debug
 ---> Running in 05ef359e80bf
no output option set, defaulting to --exists
Error printing disabled by default due to use of output options --exists, --atleast/exact/max-version, --list-all or no output option at all. Value of --print-errors: 1
Error printing enabled
Adding virtual 'pkg-config' package to list of known packages
Scanning directory #1 '/usr/lib/pkgconfig'
Ignoring file '..' in search directory; not a .pc file
Ignoring file '.' in search directory; not a .pc file
File 'oci8.pc' appears to be a .pc file
Will find package 'oci8' in file '/usr/lib/pkgconfig/oci8.pc'
Cannot open directory #2 '/usr/local/lib/x86_64-linux-gnu/pkgconfig' in package search path: No such file or directory
Cannot open directory #3 '/usr/local/lib/pkgconfig' in package search path: No such file or directory
Cannot open directory #4 '/usr/local/share/pkgconfig' in package search path: No such file or directory
Cannot open directory #5 '/usr/lib/x86_64-linux-gnu/pkgconfig' in package search path: No such file
or directory
Scanning directory #6 '/usr/lib/pkgconfig'
Ignoring file '..' in search directory; not a .pc file
Ignoring file '.' in search directory; not a .pc file
File 'oci8.pc' appears to be a .pc file
File 'oci8.pc' ignored, we already know about package 'oci8'
Scanning directory #7 '/usr/share/pkgconfig'
Ignoring file '..' in search directory; not a .pc file
Ignoring file '.' in search directory; not a .pc file
Must specify package names on the command line
The command '/bin/sh -c pkg-config --print-errors --debug' returned a non-zero code: 1

My oci8.pc file

prefix=/usr
instantclient=/usr/instantclient
libdir=${instantclient}
includedir=${instantclient}/sdk/include/

Name: oci8
Description: oci8 library
Version: 18.1
Libs: -L${libdir} -lclntsh
Cflags: -I${includedir}
cjbj commented 5 years ago

One of the earlier errors was about oci.h. Did you have the SDK installed? Or did you install the devel RMP but go-oci8 doesn't know how to find the headers? Build snafus like this are one reason why the ODPI-C layer (used by Python cx_Oracle, Node.js node-oracledb, Go goracle etc) doesn't need Oracle header files installed.

In another of your updates it looks like you are doing an unzip follow by creating some sym links. The unzip from the default packages in at least 18.3 onwards will create any needed symlinks. Is there any reason to use your own zip file? I could understand it if you removed all the unnecessary libraries, but it looks like you still include libocci which I don't think go-oci8 uses.

MichaelS11 commented 5 years ago

The oci8.pc file is showing /usr/instantclient but the folder structure that was posted is showing /opt/instantclient . Which is the correct path?

MichaelS11 commented 5 years ago

Are you getting the correct download from here? https://www.oracle.com/database/technologies/instant-client/downloads.html

I see instantclient_18_3.zip which makes me wonder if you are installing the Windows version? Is there a reason why you are not using the rpm version instead of the zip version? Make sure to get and install both the Basic Package and SDK Package.

MichaelS11 commented 5 years ago

@fabulias Figured this out?

fabulias commented 4 years ago

The oci8.pc file is showing /usr/instantclient but the folder structure that was posted is showing /opt/instantclient . Which is the correct path?

@MichaelS11 sorry, I had many problems to retake this, I'm back with all to finish this. This error was my mistake, the correct path to instantclient is /opt.

I try with other Dockerfile and other oci8.pc and the results are good!! please confirm me.

Dockerfile

FROM golang:1.12.7

RUN apt-get update
RUN apt-get install -y pkg-config && \
    apt-get install -y libaio1 && \
    apt-get install unzip

ENV CLIENT_FILENAME instantclient_18_3.zip
COPY /oracle/${CLIENT_FILENAME} .
COPY /oracle/oci8.pc /usr/lib/pkgconfig/oci8.pc

ENV PKG_CONFIG_PATH /usr/lib/pkgconfig
RUN ls -lha /usr/lib/pkgconfig
ENV LD_LIBRARY_PATH /opt/instantclient

RUN unzip ${CLIENT_FILENAME} -d /opt
RUN ls -lha /opt/instantclient &&  \
    ln -s /opt/instantclient/libclntsh.so.18.1 /opt/instantclient/libclntsh.so && \
    ln -s /opt/instantclient/libclntshcore.so.18.1 /opt/instantclient/libclntshcore.so && \
    ln -s /opt/instantclient/libocci.so.18.1 /opt/instantclient/libocci.so

RUN go get -u github.com/mattn/go-oci8

oci8.pc (we use this in our server)

prefix=/opt/instantclient
exec_prefix=${prefix}
libdir=${prefix}
includedir=${prefix}/sdk/include

Name: oci8
Description: oci8 library
Libs: -L${libdir} -lclntsh
Cflags: -I${includedir}
Version: 12.2
MichaelS11 commented 4 years ago

Glad to hear it is working for you :)

Please feel free to close the issue.

cjbj commented 4 years ago

@fabulias you could reduce disk footprint by removing some of the Instant Client libraries. Take a look at some of the Dockerfiles in https://static.rainfocus.com/oracle/oow19/sess/1553560683840001mfXq/PF/DEV4626-Developing-and-Deploying-Python-and-Node.js-Applications-in-Docker_1568845042122001Vsfl.pdf