如何基于Dockerfile构建层

本文以Node.js安装Puppeteer依赖为例,介绍如何基于Dockerfile构建层。

背景信息

函数计算提供了多种构建层的方式,对于不包含动态链接库的依赖(例如纯Python库),可直接使用控制台在线安装依赖的方式或使用本地构建的方式构建层。依赖中包含动态链接库,或者本地环境与函数计算的运行时环境不兼容时,不支持通过控制台或本地构建的方式构建层,只能基于Dockerfile构建层。

构建层时,各个语言的依赖库建议按照页面创建自定义层的说明打包到层ZIP包的指定目录下。例如,Python库打包到层ZIP包的/python目录下。如果依赖库中包含动态链接库,建议将动态链接库放到层ZIP包的/lib目录下。使用内置运行时,会默认将目录/opt/lib添加到路径LD_LIBRARY_PATH;使用自定义运行时,则需要手动添加。

构建Puppeteer层

步骤一:准备Dockerfile文件

示例如下。

FROM aliyunfc/runtime-nodejs14:build-latest

ENV PATH /opt/bin:$PATH
ENV LD_LIBRARY_PATH /opt/lib
ENV NODE_PATH /opt/nodejs/node_modules
WORKDIR /tmp

# 安装Puppeteer库到/opt/nodejs目录
COPY ./package.json /opt/nodejs/
RUN cd /opt/nodejs \
    && npm --registry https://registry.npm.taobao.org i

# 将需要安装到系统依赖库的.deb文件下载到/tmp/install/archives目录。
RUN mkdir -p /opt/lib /tmp/install
RUN apt-get update && apt-get install -y -d -o=dir::cache=/tmp/install \
    libblas3 fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 \
    libgtk-3-0 libnspr4 libnss3 libpangocairo-1.0-0 libxcb-dri3-0 \
    libx11-xcb1 libxcb1 libxss1 libxtst6 lsb-release \
    xdg-utils libatspi2.0-0 libatk1.0-0 libxkbcommon0 libepoxy0 \
    libglapi-mesa libnspr4 libgbm-dev \
    --reinstall --no-install-recommends

RUN for f in $(ls /tmp/install/archives/*.deb); do \
        echo "Preparing to unpack ${f##*/}"; \
        cd /tmp/install/archives; \
        dpkg-deb -x ${f##*/} /tmp/install; \
    done;

# 拷贝安装的.so文件到/opt/lib目录。
RUN cp -r /tmp/install/usr/bin /opt/; \
    cp -r /tmp/install/usr/lib/x86_64-linux-gnu/* /opt/lib/

# zip file
# -y   store symbolic links as the link instead of the referenced file
# .[^.]*    including hidden files and exclude the parent directory
RUN cd /opt \
    && zip -ry layer.zip * .[^.]*

CMD ["bash"]

解析如下。

  • 函数计算提供了各种运行时的基础镜像,您可以从函数计算的基本镜像中查找对应的镜像地址。推荐使用build-latest的镜像进行构建。

    说明

    在本地构建层时,使用的基础镜像的运行时版本需要和函数的运行时版本保持一致。

    FROM aliyunfc/runtime-nodejs14:build-latest
  • 声明环境变量,并指定工作目录/tmp

  • ENV PATH /opt/bin:$PATH
    ENV LD_LIBRARY_PATH /opt/lib
    ENV NODE_PATH /opt/nodejs/node_modules
    WORKDIR /tmp
  • 安装Puppeteer库到/opt/nodejs目录。

  • # 安装Puppeteer库到/opt/nodejs目录
    COPY ./package.json /opt/nodejs/
    RUN cd /opt/nodejs \
        && npm --registry https://registry.npm.taobao.org i
  • 将需要安装到系统依赖库的.deb文件下载到/tmp/install/archives目录。

  • # 将需要安装到系统依赖库的.deb文件下载到/tmp/install/archives目录。
    RUN mkdir -p /opt/lib /tmp/install
    RUN apt-get update && apt-get install -y -d -o=dir::cache=/tmp/install \
        libblas3 fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 \
        libgtk-3-0 libnspr4 libnss3 libpangocairo-1.0-0 libxcb-dri3-0 \
        libx11-xcb1 libxcb1 libxss1 libxtst6 lsb-release \
        xdg-utils libatspi2.0-0 libatk1.0-0 libxkbcommon0 libepoxy0 \
        libglapi-mesa libnspr4 libgbm-dev \
        --reinstall --no-install-recommends
  • 依次将.deb文件下载到/tmp/install目录。

  • RUN for f in $(ls /tmp/install/archives/*.deb); do \
            echo "Preparing to unpack ${f##*/}"; \
            cd /tmp/install/archives; \
            dpkg-deb -x ${f##*/} /tmp/install; \
        done;
  • 拷贝安装的.so文件到/opt/lib目录。

  • # 拷贝安装的.so文件到/opt/lib目录。
    RUN cp -r /tmp/install/usr/bin /opt/; \
        cp -r /tmp/install/usr/lib/x86_64-linux-gnu/* /opt/lib/
  • /opt/lib目录下的文件打包成ZIP格式的压缩包,注意添加-y参数保留软链接。

  • # zip file
    # -y   store symbolic links as the link instead of the referenced file
    # .[^.]*    including hidden files and exclude the parent directory
    RUN cd /opt \
        && zip -ry layer.zip * .[^.]*

步骤二:构建层ZIP包

  1. 执行以下命令,使用Dockerfile文件打包镜像。

    sudo docker build -t ${layer-image-name} -f Dockerfile .
  2. 执行以下命令,将层ZIP包从镜像中拷贝出来。

    sudo docker run --rm -v $(pwd):/tmp ${layer-image-name} sh -c "cp /opt/layer.zip /tmp/"

步骤三:创建自定义层

通过控制台或者Serverless Devs创建层。具体操作,请参见创建自定义层

说明

函数计算已将Puppeteer制作为官方公共层,您也可以直接使用。具体操作,请参见示例一:基于Node.js 16和Puppeteer实现网页截图示例程序

函数计算的基本镜像

更多信息,请参见函数计算基本镜像