【问题标题】:How to COPY library files between stages of a multi-stage Docker build while preserving symlinks?如何在多阶段 Docker 构建的阶段之间复制库文件,同时保留符号链接?
【发布时间】:2019-04-16 07:40:15
【问题描述】:

我有一个 Dockerfile,它分为两阶段多阶段 docker 构建。第一阶段生成一个基本的 gcc 构建环境,其中编译了许多 C 和 C++ 库。第二阶段使用COPY --from= 命令将库文件从第一阶段/usr/local/lib/libproto* 复制到当前图像。

我看到的问题是第一个图像包含从通用库文件名到特定版本文件名的符号链接。 AFAIK 这是 Debian 和许多其他 Linux 系统中的常见做法。 Docker 的COPY 命令似乎不理解符号链接,因此制作了库文件的两个完整副本。这会导致更大的 Docker 映像大小和来自后来的 apt-get 命令的警告,以适应 ldconfig: /usr/local/lib/libprotobuf.so.17 is not a symbolic link


我的具体文件目前看起来像:

#Compile any tools we cannot install from packages
FROM gcc:7 as builder
USER 0
RUN \
  apt-get -y update && \
  apt-get -y install \
    clang \
    libc++-dev \
    libgflags-dev \
    libgtest-dev
RUN \
  # Protocol Buffer & gRPC
  # install protobuf first, then grpc
  git clone -b $(curl -L https://grpc.io/release) \
      https://github.com/grpc/grpc /var/local/git/grpc && \
    cd /var/local/git/grpc && \
    git submodule update --init && \
    echo "--- installing protobuf ---" && \
    cd third_party/protobuf && \
    ./autogen.sh && ./configure --enable-shared && \
    make -j$(nproc) && make install && make clean && ldconfig && \
    echo "--- installing grpc ---" && \
    cd /var/local/git/grpc && \
    make -j$(nproc) && make install && make clean && ldconfig


FROM debian
LABEL \
 Description="Basic Debian production environment with a number of libraries configured" \
 MAINTAINER="Mr Me"
ARG prefix=/usr/local
ARG binPath=$prefix/bin
ARG libPath=$prefix/lib
# Copy over pre-made tools
# Protocol Buffer
COPY --from=builder /usr/local/lib/libproto* $libPath/
# gRPC
COPY --from=builder /usr/local/lib/libaddress_sorting.so.6.0.0 $libPath/
COPY --from=builder /usr/local/lib/libgpr* $libPath/
COPY --from=builder /usr/local/lib/libgrpc* $libPath/
RUN ldconfig
# Install remaining tools using apt-get
RUN apt-get -y update && \
  apt-get -y install \
    libhdf5-dev \
    libssl1.1 \
    uuid-dev;

如您所见,我正在尝试将最新版本的 gRPC 和协议缓冲区添加到基于 Debian 的运行时映像中。

【问题讨论】:

  • 作为一种解决方法,您可以 tar 文件,复制 tarball,然后在第二个容器中解压缩它们。这将保留链接。
  • @JacobTomlinson 这是一个笨拙的答案,但您的建议可能是唯一的答案。请问,你能以答案的形式给出吗?
  • 它太笨重了,我不觉得我应该 XD。我现在就按你的要求做。

标签: c++ docker shared-libraries dockerfile docker-multi-stage-build


【解决方案1】:

这更像是一种解决方法而不是答案。

您可以 tar 文件,将 tarball 复制到第二个容器,然后解压缩它们。

默认为maintains symbolic links

【讨论】:

  • 接受这个答案,因为它是我最终选择的路径。看起来 Docker 系统将来可能会更新以本地处理符号链接,但在那之前这是最好的解决方案。
  • @TafT 你有没有遇到像我描述的here 的问题?不幸的是,我无法让它以这种方式运行。
  • @FlorianBlume 很久以前我就可以肯定地说了。我看了看,可能发现了您链接到的问题的问题。
猜你喜欢
  • 2020-01-14
  • 1970-01-01
  • 2019-03-25
  • 2020-12-15
  • 1970-01-01
  • 2016-12-16
  • 1970-01-01
  • 2013-11-15
  • 1970-01-01
相关资源
最近更新 更多