【问题标题】:Oracle on Alpine linux高山 linux 上的 Oracle
【发布时间】:2019-04-15 06:44:25
【问题描述】:

我正在尝试在我的 Alpine Linux Docker 环境中安装 OCI8 扩展。虽然有几个地方说它不起作用,但也有一些地方说它确实有效。我有一个3.4 版本,出于公司原因,它现在保持不变。

我已经在我的 Docker conf 中完成了这项工作:

# Install Oracle Client and build OCI8 (Oracel Command Interface 8 - PHP extension)
USER root
ENV LD_LIBRARY_PATH=/usr/local/instantclient
ENV ORACLE_HOME=/usr/local/instantclient

RUN apk update && apk upgrade
RUN apk add musl-dev libaio autoconf && apk add --update make

## Unzip Instant Client v12
RUN pecl channel-update pecl.php.net
COPY instantclient_12_2.zip /var/www/html/instantclient_12_2.zip
RUN unzip -d /usr/local/ /var/www/html/instantclient_12_2.zip
RUN ln -s /usr/local/instantclient_12_2 /${ORACLE_HOME} && \
    ln -s /${ORACLE_HOME}/libclntsh.so.* /${ORACLE_HOME}/libclntsh.so && \
    ln -s /${ORACLE_HOME}/libocci.so.* /${ORACLE_HOME}/libocci.so && \
    ln -s /${ORACLE_HOME}/lib* /usr/lib && \
    ln -s /${ORACLE_HOME}/sqlplus /usr/bin/sqlplus &&\
    ln -s /usr/lib/libnsl.so.2.0.0  /usr/lib/libnsl.so.1

RUN apk add gcc; exit 0 # This has a history of failing sometimes

RUN echo "instantclient,/usr/local/instantclient" | pecl install oci8 &&\
    echo 'extension=oci8.so' > /usr/local/etc/php/conf.d/30-oci8.ini &&\
    rm -rf /tmp/*.zip /var/cache/apk/* /tmp/pear/

现在构建通过了,看起来还不错,但是当我执行php -v 时,我得到以下信息:

PHP 警告:PHP 启动:无法加载动态库 '/usr/local/lib/php/extensions/no-debug-non-zts-20160303/oci8.so' - 加载共享库 libnsl.so.1 时出错:没有这样的文件或目录 (/usr/local/instantclient/libclntsh.so.12.1 需要)在 Unknown on 第 0 行

PHP 版本为7.1.12

我尝试做的是apk add libnsl,但这会返回这个错误:

错误:不可满足的约束:so:libtirpc.so.3(缺失):

所以我也尝试添加apk add libtirpc-dev(“普通”libtirpc 不适用于我的版本或其他内容),但这并没有改变。

有什么线索吗?

【问题讨论】:

    标签: php oracle docker alpine


    【解决方案1】:

    我分享了我为与最新版本的 alpine 和 Instantclient basiclite 一起工作而制作的 docker 版本。 docker 镜像的大小为 124 mb。

    我分享了我的github,你可以在哪里下载它

    Docker + alpine + Instantclient Basiclite

    或者你可以在下面看到dockerfile的内容

    FROM alpine:latest
    # Install Instantclient Basic Light Oracle and Dependencies
    RUN apk --no-cache add libaio libnsl libc6-compat curl && \
    cd /tmp && \
    curl -o instantclient-basiclite.zip https://download.oracle.com/otn_software/linux/instantclient/instantclient-basiclite-linuxx64.zip -SL && \
    unzip instantclient-basiclite.zip && \
    mv instantclient*/ /usr/lib/instantclient && \
    rm instantclient-basiclite.zip && \
    ln -s /usr/lib/instantclient/libclntsh.so.19.1 /usr/lib/libclntsh.so && \
    ln -s /usr/lib/instantclient/libocci.so.19.1 /usr/lib/libocci.so && \
    ln -s /usr/lib/instantclient/libociicus.so /usr/lib/libociicus.so && \
    ln -s /usr/lib/instantclient/libnnz19.so /usr/lib/libnnz19.so && \
    ln -s /usr/lib/libnsl.so.2 /usr/lib/libnsl.so.1 && \
    ln -s /lib/libc.so.6 /usr/lib/libresolv.so.2 && \
    ln -s /lib64/ld-linux-x86-64.so.2 /usr/lib/ld-linux-x86-64.so.2
    
    ENV ORACLE_BASE /usr/lib/instantclient
    ENV LD_LIBRARY_PATH /usr/lib/instantclient
    ENV TNS_ADMIN /usr/lib/instantclient
    ENV ORACLE_HOME /usr/lib/instantclient
    

    【讨论】:

      【解决方案2】:

      我可能会迟到回答这个问题。我遇到了同样的问题,即拥有一个 alpine 基础映像并向其中添加 oracle 客户端。所以我想出了这个解决方案 - https://github.com/Shrinidhikulkarni7/OracleClient_Alpine

      这是 Dockerfile,但您还需要其中的 shell 脚本才能工作。

      FROM alpine:latest
      
      ENV LD_LIBRARY_PATH=/lib
      
      RUN wget https://download.oracle.com/otn_software/linux/instantclient/193000/instantclient-basic-linux.x64-19.3.0.0.0dbru.zip && \
          unzip instantclient-basic-linux.x64-19.3.0.0.0dbru.zip && \
          cp -r instantclient_19_3/* /lib && \
          rm -rf instantclient-basic-linux.x64-19.3.0.0.0dbru.zip && \
          apk add libaio
      
      ADD script.sh /root/script.sh
      
      RUN /root/script.sh
      
      

      这里我直接下载oracle客户端内部镜像,设置路径,添加包,最后使用shell脚本创建符号链接。

      【讨论】:

      • 如何用它构建pdo_oci php 扩展?
      • 为什么是外部脚本而不是运行命令?
      • 我已经在 GitHub 上更新了。完全忘了在这里更新@JohanBoulé
      • @mvorisek 不太确定。如果您知道,请发送 PR。
      • @ShrinidhiKulkarni 我不知道你使用的是OCI(C API)还是OCCI(C++ API),但经过大量尝试,我得出的结论是没有办法让Musl与OCCI兼容,而且我们需要将完整的 GLibC“堆栈”安装在一个单独的目录中,这首先违背了使用 Alpine 的目的。
      【解决方案3】:

      我建议使用 Oracle 支持的操作系统,这样可以避免黑客攻击 Alpine 的麻烦以及在关键时刻不会崩溃的不确定性。从而给您一些信心,您的业务不会受到负面影响。试试https://github.com/oracle/docker-images/tree/master/OracleInstantClient

      其他cmets

      • 使用 Instant Client 时不要设置 ORACLE_HOME。该变量是 完整的软件安装。
      • 使用ldconfig设置系统库路径,见 Instant Client 安装说明,例如here
      • 使用 Instant Client 19,它可以连接到与 12.2 相同的数据库版本。 (19 确实是新版本系统中重命名的终端 12.2 版本)
      • 使用 Oracle Linux Docker 映像的优势在于它可以下载和安装 19 Instant Client,而无需您手动进行下载。

      请参阅this blog,了解有关它使用的“超薄”Oracle Linux 容器的信息。

      【讨论】:

      • 虽然切换到可能支持它的东西是常识,但其背后的原因是因为一个大容器是由我们的公司产品制成的,并且切换不是微不足道的(你已经很久没有评论了这个,但我想迟到总比没有好:))
      • 我认为对于很多人来说,Oracle 客户端只会构成 Docker 映像的一个组件,因此仅仅为了与 Oracle 客户端兼容而转向 Oracle Linux 可能不是某些人的答案。就我个人而言,我使用的是基于 Oracle Linux 的 Docker 镜像,它利用了客户端,但我发现在某些情况下,Oracle Linux 并没有为我需要的其他工具提供适当的支持! Alpine 有什么特别的问题吗?
      • 让 Instantclient 在 Oracle Linux 以外的所有平台上工作至少可以说是有问题的。我倾向于选择阻力最小的路径...
      【解决方案4】:

      这里是使用 ORACLE-CLIENT 的 Golang 的 Dockerfile

      FROM golang:alpine
      
      RUN apk update
      
      ENV CLIENT_FILENAME instantclient-basic-linux.x64-12.1.0.1.0.zip
      
      WORKDIR /opt/oracle/lib
      
      ADD https://github.com/bumpx/oracle-instantclient/raw/master/${CLIENT_FILENAME} .
      
      RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories && \
      apk add --update libaio libnsl && \
      ln -s /usr/lib/libnsl.so.2 /usr/lib/libnsl.so.1
      
      RUN LIBS="*/libociei.so */libons.so */libnnz12.so */libclntshcore.so.12.1 */libclntsh.so.12.1" && \
      unzip ${CLIENT_FILENAME} ${LIBS} && \
      for lib in ${LIBS}; do mv ${lib} /usr/lib; done && \
      ln -s /usr/lib/libclntsh.so.12.1 /usr/lib/libclntsh.so && \
      rm ${CLIENT_FILENAME}
      
      RUN mkdir /app
      
      ADD . /app
      
      WORKDIR /app
      
      RUN apk add git
      RUN apk add libc-dev
      RUN apk add gcc
      
      RUN go mod tidy
      RUN go build -o main .
      
      CMD ["/app/main"]
      

      【讨论】:

        【解决方案5】:

        我刚刚使用 Godror Golang Driver for Oracle 解决了与此类似的问题。在使用 Alpine 图像时,我永远无法解决这个问题。问题最终出现了 libint.sh,永远无法完全安装以被系统识别。甚至将 docker 文件更改为使用 Glibc 库。

        我最终解决问题的方法是使用 Oracle 本身的图像。完整版不是在这里可以看到的苗条图像:https://github.com/oracle/docker-images/tree/master/OracleLinuxDevelopers

        如果需要,您必须安装 golang,然后安装 Instant 客户端和 Oracle 依赖项。

        FROM oraclelinux:7 as builder
        RUN yum install -y oracle-golang-release-el7 && \
            yum install -y git && \
            yum install -y golang unzip
        
        COPY . /app
        RUN go version
        WORKDIR /app
        {Your Docker Specific Commands Here}
        
        {Insert Build Specific Environment Variables here}
        #Oracle Specific Environment Variables
        {Insert Oracle Env Variables here}
        
        WORKDIR /root/
        #Install oracle dependencies
        RUN yum install -y wget unzip libaio && \
            rm -rf /var/cache/yum
        #install Oracle Instant Client
        RUN wget https://download.oracle.com/otn_software/linux/instantclient/199000/instantclient-basic-linux.x64-19.9.0.0.0dbru.zip -O /tmp/instantclient.zip && \
            unzip /tmp/instantclient.zip -d /usr/lib/instantclient && \
            rm /tmp/instantclient.zip
        
        #Install Oracle SDK
        RUN wget https://download.oracle.com/otn_software/linux/instantclient/199000/instantclient-sdk-linux.x64-19.9.0.0.0dbru.zip -O /tmp/instantclient-sdk-linux.x64-19.9.0.0.0.zip && \
            unzip /tmp/instantclient-sdk-linux.x64-19.9.0.0.0.zip -d /usr/lib/ && \
            rm /tmp/instantclient-sdk-linux.x64-19.9.0.0.0.zip
        
        #Install Oracle Tools through SQLPlus
        RUN wget https://download.oracle.com/otn_software/linux/instantclient/199000/instantclient-sqlplus-linux.x64-19.9.0.0.0dbru.zip -O /tmp/instantclient-sqlplus-linux.x64-19.9.0.0.0.zip && \
            unzip /tmp/instantclient-sqlplus-linux.x64-19.9.0.0.0.zip -d /usr/lib/ && \
            rm /tmp/instantclient-sqlplus-linux.x64-19.9.0.0.0.zip
        
        WORKDIR /app
        
        COPY --from=builder /app/cmd/svr .
        EXPOSE 8000
        
        CMD ["./app"]
        

        这也是我解决 Golang API 问题的方法。可能还有其他人解决了 Alpine 问题,但即使使用旧版本的 Oracle Instant Client,我也无法使其正常工作。

        【讨论】:

          【解决方案6】:

          试试这个 Docker 文件。从基本的 alpine linux 镜像开始,添加所需的包。

          FROM alpine:3.13
          
          WORKDIR /project
          
          RUN wget https://download.oracle.com/otn_software/linux/instantclient/211000/instantclient-basiclite-linux.x64-21.1.0.0.0.zip -qO- | busybox  unzip -q - && \
              wget https://download.oracle.com/otn_software/linux/instantclient/211000/instantclient-sqlplus-linux.x64-21.1.0.0.0.zip -qO- | busybox  unzip -q - && \
              wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.33-r0/glibc-2.33-r0.apk -q
          
          RUN apk add --allow-untrusted libaio glibc-2.33-r0.apk
          
          RUN cd instantclient_21_1 && cp /usr/lib/libaio.so.1 /lib/libc.musl-x86_64.so.1 . && chmod +x sqlplus
          
          ENV LD_LIBRARY_PATH=/project/instantclient_21_1
          
          

          【讨论】:

          • 为什么要同时混合musl和glibc?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-08-03
          • 2019-12-22
          • 2019-11-27
          • 2018-02-04
          • 2022-11-17
          • 2019-04-22
          • 2018-06-16
          相关资源
          最近更新 更多