基于Docker多阶段构建优化带共享库的C应用镜像大小
优化依赖多共享库的C应用Docker镜像体积方案及问题解决
问题背景
我有一个依赖多个共享库的C应用,其中部分库是从GitHub下载源码后在容器中编译安装的。由于构建过程需要安装大量构建工具和依赖,最终镜像体积达到了约564MB,希望能减小镜像体积。我考虑了两种优化方案:
- 使用静态库:看似简单,但需要将部分现有共享库转换为静态库,操作复杂度较高;
- Docker多阶段构建:在builder容器中构建共享库和应用,再将产物复制到final容器中。
应用依赖的共享库列表
通过ldd命令查看,应用依赖的共享库如下:
ldd anomapp linux-vdso.so.1 (0x00007ffcfa7fe000) librdkafka.so.1 => /usr/local/lib/librdkafka.so.1 (0x00007f9ad3c91000) libbgpstream.so.3 => /usr/local/lib/libbgpstream.so.3 (0x00007f9ad3c52000) libhiredis.so.1.1.0 => /usr/local/lib/libhiredis.so.1.1.0 (0x00007f9ad3c3c000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9ad3a4a000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9ad38fb000) libcurl.so.4 => /lib/x86_64-linux-gnu/libcurl.so.4 (0x00007f9ad3868000) libzstd.so.1 => /lib/x86_64-linux-gnu/libzstd.so.1 (0x00007f9ad37bd000) libssl.so.1.1 => /lib/x86_64-linux-gnu/libssl.so.1.1 (0x00007f9ad372a000) libcrypto.so.1.1 => /lib/x86_64-linux-gnu/libcrypto.so.1.1 (0x00007f9ad3454000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f9ad3438000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9ad3432000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9ad340f000) /lib64/ld-linux-x86-64.so.2 (0x00007f9ad3ef2000) libparsebgp.so.2 => /usr/local/lib/libparsebgp.so.2 (0x00007f9ad33f4000) libwandio.so.6 => /usr/local/lib/libwandio.so.6 (0x00007f9ad33e5000) libnghttp2.so.14 => /lib/x86_64-linux-gnu/libnghttp2.so.14 (0x00007f9ad33bc000) libidn2.so.0 => /lib/x86_64-linux-gnu/libidn2.so.0 (0x00007f9ad339b000) librtmp.so.1 => /lib/x86_64-linux-gnu/librtmp.so.1 (0x00007f9ad337b000) libssh.so.4 => /lib/x86_64-linux-gnu/libssh.so.4 (0x00007f9ad330d000) libpsl.so.5 => /lib/x86_64-linux-gnu/libpsl.so.5 (0x00007f9ad32f8000) libgssapi_krb5.so.2 => /lib/x86_64-linux-gnu/libgssapi_krb5.so.2 (0x00007f9ad32ab000) libldap_r-2.4.so.2 => /lib/x86_64-linux-gnu/libldap_r-2.4.so.2 (0x00007f9ad3255000) liblber-2.4.so.2 => /lib/x86_64-linux-gnu/liblber-2.4.so.2 (0x00007f9ad3244000) libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 (0x00007f9ad3236000) libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f9ad3221000) libunistring.so.2 => /lib/x86_64-linux-gnu/libunistring.so.2 (0x00007f9ad309f000) libgnutls.so.30 => /lib/x86_64-linux-gnu/libgnutls.so.30 (0x00007f9ad2ec9000) libhogweed.so.5 => /lib/x86_64-linux-gnu/libhogweed.so.5 (0x00007f9ad2e92000) libnettle.so.7 => /lib/x86_64-linux-gnu/libnettle.so.7 (0x00007f9ad2e58000) libgmp.so.10 => /lib/x86_64-linux-gnu/libgmp.so.10 (0x00007f9ad2dd4000) libkrb5.so.3 => /lib/x86_64-linux-gnu/libkrb5.so.3 (0x00007f9ad2cf5000) libk5crypto.so.3 => /lib/x86_64-linux-gnu/libk5crypto.so.3 (0x00007f9ad2cc4000) libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007f9ad2cbd000) libkrb5support.so.0 => /lib/x86_64-linux-gnu/libkrb5support.so.0 (0x00007f9ad2cae000) libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f9ad2c92000) libsasl2.so.2 => /lib/x86_64-linux-gnu/libsasl2.so.2 (0x00007f9ad2c75000) libgssapi.so.3 => /lib/x86_64-linux-gnu/libgssapi.so.3 (0x00007f9ad2c2e000) libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 (0x00007f9ad2c0b000) libp11-kit.so.0 => /lib/x86_64-linux-gnu/libp11-kit.so.0 (0x00007f9ad2ad5000) libtasn1.so.6 => /lib/x86_64-linux-gnu/libtasn1.so.6 (0x00007f9ad2abf000) libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1 (0x00007f9ad2ab8000) libheimntlm.so.0 => /lib/x86_64-linux-gnu/libheimntlm.so.0 (0x00007f9ad2aaa000) libkrb5.so.26 => /lib/x86_64-linux-gnu/libkrb5.so.26 (0x00007f9ad2a17000) libasn1.so.8 => /lib/x86_64-linux-gnu/libasn1.so.8 (0x00007f9ad2971000) libhcrypto.so.4 => /lib/x86_64-linux-gnu/libhcrypto.so.4 (0x00007f9ad2939000) libroken.so.18 => /lib/x86_64-linux-gnu/libroken.so.18 (0x00007f9ad2920000) libffi.so.7 => /lib/x86_64-linux-gnu/libffi.so.7 (0x00007f9ad2914000) libwind.so.0 => /lib/x86_64-linux-gnu/libwind.so.0 (0x00007f9ad28e8000) libheimbase.so.1 => /lib/x86_64-linux-gnu/libheimbase.so.1 (0x00007f9ad28d6000) libhx509.so.5 => /lib/x86_64-linux-gnu/libhx509.so.5 (0x00007f9ad2888000) libsqlite3.so.0 => /lib/x86_64-linux-gnu/libsqlite3.so.0 (0x00007f9ad275f000) libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007f9ad2724000)
多阶段构建操作及问题解决
我采用多阶段构建方案,将builder容器中编译好的库复制到生产容器中,复制命令如下:
# 复制前一阶段构建的库文件 COPY --from=builder /usr/local/lib/* /usr/local/lib/
最初执行后遇到了共享库找不到的问题,后来发现需要执行ldconfig命令更新系统的库缓存,添加以下代码后问题解决:
RUN ldconfig /usr/local/lib RUN export LD_LIBRARY_PATH="/lib:/usr/lib:/usr/local/lib" RUN ldconfig -v
内容的提问来源于stack exchange,提问作者codingfreak
相关产品推荐
相关产品推荐

