I'm trying to run my Django application in Docker, but I'm getting an error: cx_Oracle.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: "/root/lib/oracle/instantclient_23_4/libclntsh.so: cannot open shared object file: No such file or directory"
The application itself runs on PostgreSQL, but also has a connection to Oracle
OS: Ubuntu Server
I installed instantclient, and created an env variable via ~/.bashrc using the command: export LD_LIBRARY_PATH=/root/lib/oracle/instantclient_23_4:$LD_LIBRARY_PATH, and added an initialization line in the python file: cx_Oracle.init_oracle_client(lib_dir="root/lib/oracle/instantclient_23_4"), but I still get the above error.
If I run the file directly: python3 omega_db.py, the script works fine and shows the database connection, but if I run it through docker-compose up, I get the error.
The easiest solution is to use the latest version of cx_Oracle. It was renamed python-oracledb and doesn't need Instant Client, see the release announcement. Install with:
$ python3 -m pip install oracledb
Then change your code following Steps to Upgrade to python-oracledb and, in your case, removing all calls to init_oracle_client()
so you don't invoke Instant Client.
If you are using Django 5, you are good to go: see Django 5.0 supports python-oracledb natively. If you are still using an older version then see Using python-oracledb 1.0 with SQLAlchemy, Pandas, Django and Flask and add those few extra lines to your settings file:
import sys
import oracledb
oracledb.version = "8.3.0"
sys.modules["cx_Oracle"] = oracledb
If you must use cx_Oracle, then follow best practices for library path configuration and use ldconfig
instead of setting LD_LIBRARY_PATH
. It sounds like you are setting the variable in the wrong layer. Read Docker for Oracle Database Applications in Node.js and Python.
Try this in the layer where Python will run:
$ echo /root/lib/oracle/instantclient_23_4 > /etc/ld.so.conf.d/oic.conf
$ ldconfig