Docker镜像是Docker容器的基础,它包含了运行应用程序所需的所有文件和依赖,有时候我们会发现Docker镜像的大小过大,这可能会导致存储空间不足、部署时间过长等问题,优化Docker镜像大小是非常必要的,本文将介绍一些优化Docker镜像大小的方法。
(图片来源网络,侵删)
1、使用较小的基础镜像
Docker镜像是基于基础镜像构建的,因此选择一个较小的基础镜像可以有效地减小镜像大小,Alpine Linux是一个轻量级的Linux发行版,其镜像大小通常比其他Linux发行版的镜像小很多,在编写Dockerfile时,可以考虑使用Alpine Linux作为基础镜像。
2、移除不必要的文件和目录
在构建Docker镜像时,可以通过.dockerignore文件来指定需要忽略的文件和目录,这样可以避免将这些不需要的文件和目录添加到镜像中,从而减小镜像大小,可以在.dockerignore文件中添加以下内容:
忽略编译生成的文件 *.o *.a 忽略日志文件 *.log 忽略配置文件 config/3、使用多阶段构建
多阶段构建可以将构建过程分为多个阶段,每个阶段只包含当前阶段所需的文件和依赖,这样可以减小最终镜像的大小,可以使用以下Dockerfile实现多阶段构建:
第一阶段:安装依赖并编译代码 FROM node:14 AS build WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build 第二阶段:将编译后的文件复制到较小的基础镜像中 FROM alpine:3.12 AS production WORKDIR /app COPY from=build /app/dist ./dist CMD ["node", "dist/app.js"]4、使用更小的文件系统
Docker默认使用aufs作为文件系统,但是aufs会占用较大的磁盘空间,可以考虑使用更小的文件系统,如busybox或overlay2,可以在Dockerfile中使用storageopt选项来设置文件系统类型:
使用overlay2文件系统 FROM platform=linux/amd64 debian:busterslim AS base RUN aptget update && aptget install y noinstallrecommends cacertificates curl gnupg iptables libcurl4 libffidev libssldev python3pip python3setuptools && rm rf /var/lib/apt/lists/* && pip3 install upgrade pip setuptools wheel && aptget purge y autoremove && rm rf /var/lib/{apt,dpkg,cache,log}/ && adduser disabledpassword gecos "" dnsutils && chmod R 777 /tmp && chown R dnsutils:dnsutils /home/dnsutils && echo "dnsutils ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && echo "deb http://deb.debian.org/debian $(lsb_release sc)backports main" > /etc/apt/sources.list.d/backports.list && aptget update && aptget y noinstallrecommends install libcap2bin libcap2bin/ping && aptget clean && rm rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/* /usr/share/man/* /home/* /root/* /var/* /etc/* /sys/* /run/* /tmp/* /var/tmp/* /usr/share/doc/* /usr/share/man/* /home/* /root/* /var/* /etc/* /sys/* /run/* && groupadd force g $PGID dnsutils && useradd ms /bin/bash nousergroup g dnsutils uid $UID dnsutils && echo "$DNSUTILS_PASSWORD" | chpasswd <<<EOF > /dev/null 2>&1 $UID:$DNSUTILS_PASSWORD EOF && chmod +x /usr/local/bin/entrypoint.sh && echo "dnsutils ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && echo "dnsutils ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && chmod u+s,g+s,o+t suexec && setcap cap_net_raw,cap_net_admin=eip /usr/local/bin/entrypoint.sh && mv /usr/local/bin/entrypoint.sh /usr/local/bin/${APP_NAME} && mv /usr/local/bin/${APP_NAME} /usr/local/bin/${APP_NAME}.bak && chmod +x /usr/local/bin/${APP_NAME}.bak && mv /usr/local/bin/${APP_NAME}.bak /usr/local/bin/${APP_NAME} && chown dnsutils:dnsutils R /home/${APP_NAME} && chown dnsutils:dnsutils R /usr/local/${APP_NAME} && chown dnsutils:dnsutils R /var/${APP_NAME} && chown dnsutils:dnsutils R /etc/${APP_NAME} && chown dnsutils:dnsutils R /run/${APP_NAME} && chown dnsutils:dnsutils R /var/${APP_NAME}/logs && chown dnsutils:dnsutils R /var/${APP_NAME}/data && chown dnsutils:dnsutils R /var/${APP_NAME}/config && chown dnsutils:dnsutils R /var/${APP_NAME}/dbdata && chown dnsutils:dnsutils R /var/${APP_NAME}/dbdata/${DB_NAME} && chown dnsutils:dnsutils R /var/${APP_NAME}/dbdata/${DB_NAME}/data && chown dnsutils:dnsutils R /var/${APP_NAME}/dbdata/${DB_NAME}/indexes && chown dnsutils:dnsutils R /var/${APP_NAME}/dbdata/${DB_NAME}/journal && chown dnsutils:dnsutils R /var/${APP_NAME}/dbdata/${DB_NAME}/schema_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_{USER}${SUPERUSER}$EOF5、使用多阶段构建和缓存策略
结合多阶段构建和缓存策略可以进一步减小Docker镜像大小,可以使用以下Dockerfile实现多阶段构建和缓存策略:
第一阶段:安装依赖并编译代码,缓存不变化的依赖项 FROM node:14 AS builddeps WORKDIR /app COPY package*.json ./ RUN npm install only=production nooptional preferoffline COPY . . RUN npm run build prod outputpath=dist cache=true 第二阶段:将编译后的文件复制到较小的基础镜像中,并缓存编译结果 FROM alpine:3.12 AS production WORKDIR /app COPY from=builddeps /app/dist ./dist COPY from=build