我正在構建一個需要連接到遠程 Oracle 資料庫的基于 Docker 的 Flask API。我可以讓它在 Docker 之外的我的機器上作業,但是當我去容器化它時,我得到了錯誤。我已經嘗試了我可以在 stackoverflow 上找到的所有文章,但仍然出現錯誤:
load by OS failure: libclntsh.so: cannot open shared object file: No such file or directory
我嘗試了 3 種不同的方法:
FROM python:3.9-buster
ENV DPI_DEBUG_LEVEL=64
# Installing Oracle instant client
# INSTALL TOOLS
RUN apt-get update \
&& apt-get -y install unzip \
&& apt-get -y install libaio1 libaio-dev \
&& mkdir -p /opt/data/api
ADD ./oracle-instantclient/ /opt/data
ADD ./install-instantclient.sh /opt/data
ADD ./requirements.txt /opt/data
WORKDIR /opt/data
ENV ORACLE_HOME=/opt/oracle/instantclient
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME
ENV OCI_HOME=/opt/oracle/instantclient
ENV OCI_LIB_DIR=/opt/oracle/instantclient
ENV OCI_INCLUDE_DIR=/opt/oracle/instantclient/sdk/include
RUN ./install-instantclient.sh
# Python set up
# set working directory
WORKDIR /usr/src/app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# add and install requirements
COPY ./requirements.txt .
RUN pip install -r requirements.txt
# add app
COPY . .
# add entrypoint.sh
COPY ./entrypoint.sh .
RUN chmod x /usr/src/app/entrypoint.sh
這是我為即時客戶端嘗試的第一種方法:
# Install system dependencies and clean up rpms afterwards
RUN apt-get update \
&& apt-get -y install alien unzip libaio1 \
&& apt-get clean
# ZIP Install
ENV DPI_DEBUG_LEVEL=64
ENV INSTANT_CLIENT_FILE=instantclient-basic-linux.x64-19.13.0.0.0dbru.zip
RUN mkdir -p /opt/oracle
ADD ./resources/${INSTANT_CLIENT_FILE} /opt/oracle
RUN apt-get -y install unzip
RUN unzip /opt/oracle/${INSTANT_CLIENT_FILE} -d /opt/oracle
RUN ln -s /opt/oracle/instantclient_19_13/libclntsh.so.19.13 /usr/lib/libclntsh.so
RUN rm -rf /opt/oracle/${INSTANT_CLIENT_FILE}
# This needs to be set to the path that was created when the unzip occurred
# I figured out what the directory name after /opt/oracle was going to be by
# unzipping the file on my computer
ENV ORACLE_HOME=/opt/oracle/instantclient_19_13
ENV LD_LIBRARY_PATH=${ORACLE_HOME}
ENV ORACLE_BASE=${ORACLE_HOME}
ENV PATH="${ORACLE_HOME}:${PATH}"
RUN sh -c "echo ${ORACLE_HOME} > /etc/ld.so.conf.d/oracle-instantclient.conf"
RUN ldconfig
然后嘗試 RPM 安裝:
# RPM Install
ENV INSTANT_CLIENT_FILE_NAME=oracle-instantclient-basic-21.4.0.0.0-1.el8.x86_64
RUN mkdir /resources
COPY ./resources/${INSTANT_CLIENT_FILE_NAME}.rpm /resources
RUN alien -ct --scripts /resources/${INSTANT_CLIENT_FILE_NAME}.rpm
#RUN alien --scripts --to-deb /resources/${INSTANT_CLIENT_FILE_NAME}.tgz
RUN apt-get -y install ./resources/${INSTANT_CLIENT_FILE_NAME}.deb
RUN rm -rf ./resources/${INSTANT_CLIENT_FILE_NAME}.rpm
RUN rm -rf ./resources/${INSTANT_CLIENT_FILE_NAME}.deb
每次我收到錯誤時,我要么直接指定了 LD_LIBRARY_PATH,要么運行了:
RUN sh -c "echo ${ORACLE_HOME} > /etc/ld.so.conf.d/oracle-instantclient.conf"
RUN ldconfig
如果我在容器中運行 ldconfig -p 然后我會看到我的條目。或者,如果我查看容器中的環境變數,一切都已設定,我可以看到它們。但是我仍然收到有關無法找到檔案的錯誤。任何其他建議將不勝感激。
uj5u.com熱心網友回復:
評論太長了,你有幾個場景,所以這里有一些想法。
使用已經有 cx_Oracle 的 Oracle 容器?在https://github.com/oracle/docker-images/pkgs/container/oraclelinux7-python上查找 *-oracledb 容器
切勿使用 Instant Client 設定 ORACLE_HOME。
那些 OCI_HOME、OCI_LIB_DIR 和 OCI_INCLUDE_DIR 變數是做什么用的?cx_Oracle 安裝或運行時不使用它們。
我在 Ubuntu 上使用 RPM:
alien -i --scripts oracle-instantclient19.13-basic-19.13.0.0.0-1.x86_64.rpm alien -i --scripts oracle-instantclient19.13-sqlplus-19.13.0.0.0-1.x86_64.rpm apt-get install libaio1
然后我不需要創建符號鏈接或運行 ldconfig。即它應該“正常作業”。
也許可以查看我的博客文章系列Docker for Oracle Database Applications in Node.js 和 Python,其中有一些適用于 Python cx_Oracle 的 Dockerfile 示例?
uj5u.com熱心網友回復:
所以我已經為此作業了兩天。我的設定中有一部分是我仔細查看的,結果證明是導致問題的原因。我使用的是 Mac Mini M1,這是我嘗試過的任何方法都不起作用的原因。我錯過了 Dockerfile 中的一個重要部分。我需要添加--platform=linux/amd64。我不知道這一點,因為我 2 天前剛剛切換到 Mac Mini,這不是我以前需要做的事情。希望如果有人遇到同樣的問題,他們會發現這一點,這會對他們有所幫助。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/360746.html
