I am trying to initialize python-oracledb in Thick Mode. It works on my Mac M1 Pro, but when I try to containerize my application with Docker, I get DPI-1047: Cannot locate a 64-bit Oracle Client library: "libclntsh.so: cannot open shared object file: No such file or directory". I followed the python-oracledb instructions (3.1.3. Enabling python-oracledb Thick Mode on Linux and Related Platforms) and tried to do what was in this post containing the same error message. I can see that it is searching in the ORACLE_HOME environment variable (even though I came across multiple posts that say not to use that when using instantclient). I don't see anywhere in the error message that it is searching in LD_LIBRARY_PATH, which is what the python-oracledb instruction say to set. I also printed the directories where the python-oracledb should be looking, and the file does in fact exist (see the error message between the =====). What is the issue here? Check out the end of the post for step-by-step instructions for what I did. Error message in container 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: ODPI-C 5.5.1 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: debugging messages initialized at level 64 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: Context Parameters: 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: Oracle Client Config Dir: /opt/oracle/network/admin 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: Environment Variables: 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: ORACLE_HOME => "/opt/oracle" 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: LD_LIBRARY_PATH => "/opt/oracle/instantclient" 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: LIBPATH => "/opt/oracle/instantclient" 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: SHLIB_PATH => "/opt/oracle/instantclient" 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: check ODPI-C module directory 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: ODPI-C module name is /usr/local/lib/python3.13/site-packages/oracledb/thick_impl.cpython-313-aarch64-linux-gnu.so 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load in dir /usr/local/lib/python3.13/site-packages/oracledb 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load with name /usr/local/lib/python3.13/site-packages/oracledb/libclntsh.so 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load by OS failure: /usr/local/lib/python3.13/site-packages/oracledb/libclntsh.so: cannot open shared object file: No such file or directory 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load with OS search heuristics 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load with name libclntsh.so 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load by OS failure: libclntsh.so: cannot open shared object file: No such file or directory 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load with name libclntsh.so.19.1 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load by OS failure: libclntsh.so.19.1: cannot open shared object file: No such file or directory 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load with name libclntsh.so.18.1 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load by OS failure: libclntsh.so.18.1: cannot open shared object file: No such file or directory 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load with name libclntsh.so.12.1 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load by OS failure: libclntsh.so.12.1: cannot open shared object file: No such file or directory 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load with name libclntsh.so.11.1 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load by OS failure: libclntsh.so.11.1: cannot open shared object file: No such file or directory 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load with name libclntsh.so.20.1 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load by OS failure: libclntsh.so.20.1: cannot open shared object file: No such file or directory 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load with name libclntsh.so.21.1 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load by OS failure: libclntsh.so.21.1: cannot open shared object file: No such file or directory 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: check ORACLE_HOME 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load in dir /opt/oracle/lib 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load with name /opt/oracle/lib/libclntsh.so 2025-05-17 20:09:40 docker-test | ODPI [00001] 2025-05-18 00:09:40.495: load by OS failure: /opt/oracle/lib/libclntsh.so: cannot open shared object file: No such file or directory 2025-05-17 20:09:40 docker-test | ================================================== 2025-05-17 20:09:40 docker-test | /opt/oracle/instantclient: 2025-05-17 20:09:40 docker-test | ['BASIC_LICENSE', 'BASIC_README', 'libclntsh.so', 'libclntsh.so.10.1', 'libclntsh.so.11.1', 'libclntsh.so.12.1', 'libclntsh.so.18.1', 'libclntsh.so.19.1', 'libclntshcore.so.19.1', 'libipc1.so', 'libmql1.so', 'libnnz19.so', 'libociei.so', 'network'] 2025-05-17 20:09:40 docker-test | 2025-05-17 20:09:40 docker-test | /opt/oracle/lib: 2025-05-17 20:09:40 docker-test | ['BASIC_LICENSE', 'BASIC_README', 'libclntsh.so', 'libclntsh.so.10.1', 'libclntsh.so.11.1', 'libclntsh.so.12.1', 'libclntsh.so.18.1', 'libclntsh.so.19.1', 'libclntshcore.so.19.1', 'libipc1.so', 'libmql1.so', 'libnnz19.so', 'libociei.so', 'network'] 2025-05-17 20:09:40 docker-test | ================================================== 2025-05-17 20:09:40 docker-test | Error initializing Oracle client: DPI-1047: Cannot locate a 64-bit Oracle Client library: "/opt/oracle/lib/libclntsh.so: cannot open shared object file: No such file or directory". See https://python-oracledb.readthedocs.io/en/latest/user_guide/initialization.html for help 2025-05-17 20:09:40 docker-test | Help: https://python-oracledb.readthedocs.io/en/latest/user_guide/troubleshooting.html#dpi-1047 2036-01-01 00:00:00 docker-test exited with code 0 Dockerfile FROM python:3.13-slim RUN apt-get update && \ apt-get install -y wget unzip libaio1 ARG ORACLE_CLIENT_HOME=/opt/oracle/instantclient WORKDIR /opt/oracle # Download and install Oracle instantclient RUN mkdir /tmp/oracle && \ wget https://download.oracle.com/otn_software/linux/instantclient/1921000/instantclient-basic-linux.x64-19.21.0.0.0dbru.zip -P /tmp/oracle && \ unzip /tmp/oracle/instantclient-basic-* -d /tmp/oracle && \ mv /tmp/oracle/instantclient_* ${ORACLE_CLIENT_HOME} && \ cd ${ORACLE_CLIENT_HOME} && rm -f *jdbc* *occi* *mysql* *jar uidrvci genezi adrci && \ echo ${ORACLE_CLIENT_HOME} > /etc/ld.so.conf.d/oracle-instantclient.conf && \ ldconfig # Copy instantclient to lib directory since # per the oracledb docs, ORACLE_HOME uses $ORACLE_HOME/lib RUN mkdir lib && cp -r instantclient/* lib ENV LIBPATH=${ORACLE_CLIENT_HOME} ENV SHLIB_PATH=${ORACLE_CLIENT_HOME} ENV LD_LIBRARY_PATH=${ORACLE_CLIENT_HOME} ENV ORACLE_HOME=/opt/oracle ENV DPI_DEBUG_LEVEL=64 RUN pip install --upgrade pip && pip install oracledb WORKDIR /app ADD main.py ./ CMD ["python", "main.py"] Here's what I did step-by-step if you want to try and recreate the error: Create a new venv (python==3.13.1 and oracledb==3.1.1). Pull the docker container from the oracle container registry: docker pull container-registry.oracle.com/database/express:21.3.0-xe Create the container: docker container create -it --name oracle -p 1521:1521 -e ORACLE_PWD=welcome123 container-registry.oracle.com/database/express:21.3.0-xe Start the container: docker start oracle Downloaded the instantclient for mac (instantclient-basic-macos.arm64-23.3.0.23.09-2.dmg) and followed the installation instructions on the download page. I moved the instantclient_23_3 folder that gets created in the Downloads folder into my project folder. Test the oracle connection in python by running python main.py. When I run in my vscode terminal, I get the output I was expecting. main.py import os from pathlib import Path import oracledb try: if os.getenv("DOCKER_CONTAINER", "false") == "false": oracledb.init_oracle_client( lib_dir=str(Path(__file__).parent.joinpath("instantclient_23_3")) ) else: print("=" * 50) print("/opt/oracle/instantclient:") print(sorted(os.listdir("/opt/oracle/instantclient"))) print() print("/opt/oracle/lib:") print(sorted(os.listdir("/opt/oracle/lib"))) print("=" * 50) oracledb.init_oracle_client() pool = oracledb.create_pool( user="system", password="welcome123", dsn="0.0.0.0:1521", min=1, max=5, increment=1, ) try: with pool.acquire() as conn: with conn.cursor() as cursor: sql = """select sysdate from dual""" for r in cursor.execute(sql): print(r) except Exception as err: print("Error with pool:", err) except oracledb.DatabaseError as err: print("Error initializing Oracle client:", err) Test the container by running docker compose up -d --build. The Dockerfile is at the top of the post and the docker-compose.yaml is below. docker-compose.yaml services: test: build: context: . dockerfile: Dockerfile image: docker-test-image container_name: docker-test environment: DOCKER_CONTAINER: "true" The project folder structure looks like this: . ├── .venv ├── instantclient_23_3 ├── docker-compose.yaml ├── Dockerfile ├── main.py ├── README.md 2 directories, 4 files Continue reading...