笔者在工作中碰到一个任务需要制作一个足够小的Docker镜像,并能够支持运行C++和第三方动态库的应用程序,同时还能够运行nodejs, 于是便有了这么一个实践并分享给读者。
步骤一:下载alpine-pkg-glibc及密钥
apk包:https://github.com/sgerrand/alpine-pkg-glibc/releases
密钥: https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
下载后保存在当前目录下lib目录
C++应用程序在当前目录下bin目录
步骤二:制作Dockerfile
FROM alpine
#use domestic apk mirror
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
#glibc apk
WORKDIR /var/lib/apk
COPY lib/ ./
RUN mv ./sgerrand.rsa.pub /etc/apk/keys/sgerrand.rsa.pub
#add apk
RUN apk add --no-cache --update nodejs
RUN apk add --no-cache glibc-2.29-r0.apk glibc-bin-2.29-r0.apk
WORKDIR /app
COPY bin/ ./
RUN chmod +x *.bin
RUN /usr/glibc-compat/sbin/ldconfig /app/thirdparty
这最后一句很关键,要用全路径指定的ldconfig来配置共享库目录,不能直接使用ldconfig。否则运行c++程序时会报错
RUN /usr/glibc-compat/sbin/ldconfig /app/thirdparty
另外调试时可以使用 ldd [应用程序路径] 命令来查看应用程序依赖的库以及哪些库找不到。
注:为了便于理解,这里省略了编译nodejs代码的过程,实际生产过程建议使用:
multistage build. https://docs.docker.com/develop/develop-images/multistage-build/
构建Docker镜像,这里因篇幅原因不详细展开。
后来笔者用centos7的基础镜像也做了个类似的支持glibc和nodejs的,进行了镜像体积的对比,alpine的只有48.3MB,非常轻量。
参考:
https://github.com/sgerrand/alpine-pkg-glibc