Closed belgoros closed 6 years ago
What type of Oracle client do you use?
If it is Oracle instant client, set the environment variable LD_LIBRARY_PATH=/path/to/instant/client/directory
and then build ruby-oci8.
https://www.rubydoc.info/github/kubo/ruby-oci8/file/docs/install-instant-client.md
@kubo I have no Oracle client installed at all. I'm on macOS and running a Rake task locally to query the Oracle DB:
Database: Oracle (ver. Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options) Identifier case sensitivity: upper (plain), exact (delimited) Driver (JDBC4.0): Oracle JDBC driver (ver. 12.1.0.2.0)
I just set up connection details in database.yml
file of a Rails app:
mystore:
adapter: oracle_enhanced
host: <%= ENV['mystore_db_host']%>
port: <%= ENV['mystore_db_port']%>
database: <%= ENV['mystore_db_name']%>
username: <%= ENV['mystore_db_user']%>
password: <%= ENV['mystore_db_password']%>
and connect a model like that:
module MystoreMigration
class MystoreModel < ApplicationRecord
establish_connection(:mystore) unless Rails.env.test?
end
end
It works just fine. But when rebuilding the docker container it fails to install the gems.
Database: Oracle (ver. Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options) Identifier case sensitivity: upper (plain), exact (delimited) Driver (JDBC4.0): Oracle JDBC driver (ver. 12.1.0.2.0)
Do you use JRuby and Oracle JDBC on macOS? If so, it is better to use JRuby and Oracle JDBC also in the docker container.
Ruby-oci8 doesn't run without Oracle client.
No, I use MRI:
#macOS
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-darwin17]
#Docker container
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]
How can you explain that I can run the rake task and just ruby code from a simple Ruby file if
Ruby-oci8 doesn't run without Oracle client.
Ruby-oci8 uses functions in Oracle client library. I bet that Oracle instant client is somewhere on the macOS.
Not sure, I've already checked homebrew formulas and the list of installed apps, there is no instantclient found.
But running sqlplus
displays the following:
sqlplus
SQL*Plus: Release 12.1.0.2.0 Production on Wed Jul 11 16:17:37 2018
Copyright (c) 1982, 2016, Oracle. All rights reserved.
Enter user-name:
I cannot explain how it works on your macOS. However ruby-oci8 depends on Oracle client. You need Oracle client in the docker image.
It is confirmed, - I have Instant Client
installed with Homebrew:
~ locate sqlplus
/Users/Serguei/soft/instantclient-sqlplus-macos.x64-12.1.0.2.0.zip
/usr/local/Cellar/instantclient-sqlplus
/usr/local/Cellar/instantclient-sqlplus/12.1.0.2.0
/usr/local/Cellar/instantclient-sqlplus/12.1.0.2.0/.brew
/usr/local/Cellar/instantclient-sqlplus/12.1.0.2.0/.brew/instantclient-sqlplus.rb
/usr/local/Cellar/instantclient-sqlplus/12.1.0.2.0/INSTALL_RECEIPT.json
/usr/local/Cellar/instantclient-sqlplus/12.1.0.2.0/bin
/usr/local/Cellar/instantclient-sqlplus/12.1.0.2.0/bin/sqlplus
/usr/local/Cellar/instantclient-sqlplus/12.1.0.2.0/lib
/usr/local/Cellar/instantclient-sqlplus/12.1.0.2.0/lib/libsqlplus.dylib
/usr/local/Cellar/instantclient-sqlplus/12.1.0.2.0/lib/libsqlplusic.dylib
/usr/local/Homebrew/Library/Taps/instantclienttap/homebrew-instantclient/Formula/instantclient-sqlplus.rb
/usr/local/Homebrew/Library/Taps/instantclienttap/homebrew-instantclient/Formula/instantclient-sqlplus11.rb
/usr/local/bin/sqlplus
/usr/local/lib/libsqlplus.dylib
/usr/local/lib/libsqlplusic.dylib
/usr/local/opt/instantclient-sqlplus
/usr/local/var/homebrew/linked/instantclient-sqlplus
/usr/local/var/homebrew/locks/instantclient-sqlplus.formula.lock
I'll close the issue. Thank you.
So event after installing Instant Client, it fails to install and I have the following error message:
Installing ruby-oci8 2.2.5.1 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
current directory: /usr/local/bundle/gems/ruby-oci8-2.2.5.1/ext/oci8
/usr/local/bin/ruby -r ./siteconf20180712-7-7chxou.rb extconf.rb
checking for load library path...
LD_LIBRARY_PATH is not set.
checking ld.so.conf... no
checking for cc... ok
checking for gcc... yes
checking for LP64... yes
checking for sys/types.h... yes
checking for ruby header... ok
...
RuntimeError (RuntimeError)
from /usr/local/bundle/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:728:in
`initialize'
from /usr/local/bundle/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:269:in `new'
from /usr/local/bundle/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:269:in `get'
from extconf.rb:22:in `<main>'
---------------------------------------------------
Error Message:
Set the environment variable ORACLE_HOME if Oracle Full Client.
Append the path of Oracle client libraries to LD_LIBRARY_PATH if Oracle
Instant Client.
Here are the comands I run when installing INstant Client in the Docker container:
RUN alien -i oracle-instantclient12.2-basiclite-12.2.0.1.0-1.x86_64.rpm
RUN alien -i oracle-instantclient12.2-devel-12.2.0.1.0-1.x86_64.rpm
RUN alien -i oracle-instantclient12.2-sqlplus-12.2.0.1.0-1.x86_64.rpm
RUN export LD_LIBRARY_PATH=/usr/lib/oracle/12.2/client64/lib:$LD_LIBRARY_PATH
RUN export PATH=/opt/oracle/instantclient_12_2:$PATH
RUN export PATH=/usr/lib/oracle/12.2/client64/bin:$PATH
And, as it can be seen from the stack trace, it seems to be OK:
Removing intermediate container 2f21739c2993
---> 239ea737eb81
Step 11/19 : RUN export LD_LIBRARY_PATH=/usr/lib/oracle/12.2/client64/lib:$LD_LIBRARY_PATH
---> Running in 78779fb15cdc
Removing intermediate container 78779fb15cdc
---> e40cd2d3f575
Step 12/19 : RUN export PATH=/opt/oracle/instantclient_12_2:$PATH
---> Running in 43eb9cae4e20
Removing intermediate container 43eb9cae4e20
---> ce12510f8ba4
Step 13/19 : RUN export PATH=/usr/lib/oracle/12.2/client64/bin:$PATH
What is the problem with ORACLE_HOME or smth else ?
checking for load library path...
LD_LIBRARY_PATH is not set.
I have not used Docker setting files. I have a question.
RUN export LD_LIBRARY_PATH=/usr/lib/oracle/12.2/client64/lib:$LD_LIBRARY_PATH
Does Docker execute all specified commands at RUN
lines in one process? Otherwise, does it execute them in each processes?
If the latter, the export LD_LIBRARY_PATH=...
at the RUN
line doesn't affect succeeding commands, so ruby-oci8 cannot find LD_LIBRARY_PATH
. If so, I guess that there is a keyword similar to RUN
to set environment variables which affect succeeding commands.
What is the problem with ORACLE_HOME or smth else ?
Oracle instant client runs without ORACLE_HOME
. Only LD_LIBRARY_PATH
is mandatory in your case.
I searched for the value I set for LD_LIBRARY_PATH
:
LD_LIBRARY_PATH=/usr/lib/oracle/12.2/client64/lib:$LD_LIBRARY_PATH
and didn't find it, it does not even exist on the specified location, - i followed the steps indicated in Oracle installation instructions. I thin that is the problem. Nevertheless, the error message coming from ruby-oci8 gem seems to be not adequate:
Error Message:
Set the environment variable ORACLE_HOME if Oracle Full Client.
Append the path of Oracle client libraries to LD_LIBRARY_PATH if Oracle
Instant Client.
Backtrace:
/usr/local/bundle/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:909:in `get_home'
/usr/local/bundle/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:728:in
`initialize'
/usr/local/bundle/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:269:in `new'
/usr/local/bundle/gems/ruby-oci8-2.2.5.1/ext/oci8/oraconf.rb:269:in `get'
extconf.rb:22:in `<main>'
even if your docs say that setting ORACLE_HOME
isn't necessary.
I'll have to figure out where the needed files are installed t be able to set LD_LIBRARY_PATH
correctly.
checking for load library path...
LD_LIBRARY_PATH is not set.
This message indicates that nothing is set to LD_LIBRARY_PATH
. It doesn't mean that the value of LD_LIBRARY_PATH
is incorrect.
In a command prompt:
export LD_LIBRARY_PATH=/usr/lib/oracle/12.2/client64/lib:$LD_LIBRARY_PATH
echo $LD_LIBRARY_PATH
The echo
command prints the content of LD_LIBRARY_PATH including /usr/lib/oracle/12.2/client64/lib
.
In the Docker container:
RUN export LD_LIBRARY_PATH=/usr/lib/oracle/12.2/client64/lib:$LD_LIBRARY_PATH
RUN echo $LD_LIBRARY_PATH
I guess that the echo
command doesn't print /usr/lib/oracle/12.2/client64/lib
because the first and second commands run under different processes. export LD_LIBRARY_PATH=...
affects only the process itself and processes created from the process. It doesn't affect other processes.
i followed the steps indicated in Oracle installation instructions.
Following instructions in a command prompt is different from following instructions under different processes. The latter case are not expected usually. What you did in Docker is similar with: (1) open a command prompt, (2) follow the first instruction, (3) close the command prompt, (4) open another command prompt, (5) follow the second instruction, (6) close the command prompt, (7) open yet another command prompt, (8) follow the third instruction, (9) close the command prompt, ...
I'll have to figure out where the needed files are installed t be able to set LD_LIBRARY_PATH correctly.
You have to figure out how to set LD_LIBRARY_PATH
in Docker firstly. What you say is the next step.
Yep, the first thing (LD_LIBRARY_PATH
) was fixed, - you were right about separate processes.
checking for load library path...
LD_LIBRARY_PATH...
checking /opt/oracle/instantclient_12_2... yes
/opt/oracle/instantclient_12_2/libclntsh.so.12.1 looks like an instant client.
There is another error now, - with libclntsh.so
:
Error Message:
Could not compile with Oracle instant client.
/opt/oracle/instantclient_12_2/libclntsh.so could not be found.
You may need to make a symbolic link.
cd /opt/oracle/instantclient_12_2
ln -s libclntsh.so.12.1 libclntsh.so
After creating the symlink, the gem was installed with success. I created a GitHub repo to demonstrate it. Hope this helps to others. Thank you.
I added the following 2 gems to my
Gemfile
:When starting a Docker container, it failed as follows:
The dockerized app works as needed, but fails just after adding these 2 gems to
Gemfile
. It works also when running locally in 'standard' way withbundle install
, thenrails s
. I'm using a standard Ruby image in Dockerfile:What's wrong here ?
Thank you.