如何减少Docker镜像的大小

mefy6pfw  于 2023-05-28  发布在  Docker
关注(0)|答案(7)|浏览(318)

我有一个Node.js应用程序,我正在作为Docker容器运行。下面是该应用程序的Dockerfile。

FROM ubuntu

ARG ENVIRONMENT
ARG PORT

RUN apt-get update -qq
RUN apt-get install -y build-essential nodejs npm nodejs-legacy vim

RUN mkdir /consumer_portal
ADD . /consumer_portal
WORKDIR /consumer_portal

RUN npm install -g express
RUN npm install -g path
RUN npm cache clean
RUN npm install

EXPOSE $PORT

ENTRYPOINT [ "node",  "server.js" ]
CMD [ $PORT, $ENVIRONMENT ]

我可以修改这个Dockerfile中的一些东西来减小docker镜像大小吗

zour9fqk

zour9fqk1#

使用the official node alpine image作为基本映像,正如这里所建议的那样,是一个简单的解决方案,可以减少映像的整体大小,因为即使是基本alpine映像也比基本ubuntu映像小得多。
Dockerfile可能看起来像这样:

FROM node:alpine

ARG ENVIRONMENT
ARG PORT

RUN mkdir /consumer_portal \
    && npm install -g express path

COPY . /consumer_portal
WORKDIR /consumer_portal

RUN npm cache clean \
    && npm install

EXPOSE $PORT

CMD [ "node",  "server.js" ]

它几乎是一样的,应该像预期的那样工作。你的ubuntu镜像中的大多数命令都可以以同样的方式应用到alpine镜像中。
当我添加mock-data来创建一个类似的项目时,结果是一个大小为491 MB的Ubuntu映像,而alpine版本只有62.5 MB大:

REPOSITORY   TAG       IMAGE ID        CREATED          SIZE
alpinefoo    latest    8ca6f338475e    5 minutes ago    62.5MB
ubuntufoo    latest    38620a1bd5a6    6 minutes ago    491MB
jutyujz0

jutyujz02#

尝试将所有RUN指令打包在一起,这样可以减少中间图像的数量。(但它不会减少最终图像的大小)。
apt-get update之后添加rm -rf /var/lib/apt/lists/*将通过删除所有无用的apt-get内容来减小图像大小。
您也可以在最后一个RUN指令中从映像中删除vim

FROM ubuntu

ARG ENVIRONMENT
ARG PORT

RUN apt-get update \
    && apt-get install -y build-essential nodejs npm nodejs-legacy vim \
    && rm -rf /var/lib/apt/lists/* \
    && mkdir /consumer_portal

ADD . /consumer_portal
WORKDIR /consumer_portal

RUN npm install -g express \
    && npm install -g path \
    && npm cache clean \
    && npm install

EXPOSE $PORT

ENTRYPOINT [ "node",  "server.js" ]
CMD [ $PORT, $ENVIRONMENT ]
62lalag4

62lalag43#

1)搬到阿尔卑斯山可能是最好的选择。我刚刚将一个Ubuntu docker文件移植到Alpine,从1.5GB增加到585 MB。我跟踪了these instructions请注意,您将使用apk而不是apt-get,并且Alpine包名称略有不同。
2)也可以通过合并运行命令来减少层(每个新运行命令创建一个新层)。

RUN apt-get update -qq && apt-get install -y build-essential nodejs npm nodejs-legacy vim
RUN npm install -g express path && npm cache clean && npm install

3)您可能还对多阶段构建感兴趣,其中您只将必要的组件复制到最终映像。

qrjkbowd

qrjkbowd4#

请考虑使用以下命令:在apt-get安装软件包时,请考虑使用--no-install-recommends。这将导致较小的图像尺寸。欲了解更多信息,请参阅此博客文章
有一个很好的博客告诉你几个步骤去减少图像大小。
减少Docker镜像大小的提示https://hackernoon.com/tips-to-reduce-docker-image-sizes-876095da3b34

7nbnzgx9

7nbnzgx95#

第一步生成的镜像,别名:建造者

将第一步图像的产品复制到当前图像,只使用一个图像层,保存上一步的图像层数。

FROM node:10-alpine as builder
WORKDIR /web-console 
ADD . /web-console
RUN npm install
RUN npm run build 

FROM node:10-alpine
WORKDIR /web-console
COPY --from=builder . /web-console
CMD ["npm", "run", "docker-start"]

这里是一个使用Maven的Java示例:2个步骤

FROM maven:3.5.2-jdk-8-alpine as BUILD
WORKDIR /app
COPY pom.xml /app/
COPY src /app/src/
RUN mvn clean package -DskipTests

FROM alpine
WORKDIR /app
COPY --from=BUILD /app/target/*.jar  application.jar
ENTRYPOINT ["java", "-jar", "/application.jar"]
anauzrmj

anauzrmj6#

如果你基于Ubuntu,那么明智的做法是

RUN apt-get update && apt-get install -y \
    build-essential \
    cwhatever-you-want \
    vim \
 && rm -rf /var/lib/apt/lists/*

最后一行会清楚很多:)你应该总是在同一行中apt-get update,因为否则它将被缓存,如果你添加另一个lib来安装,它将不会在下一个构建中被触发。

shyt4zoc

shyt4zoc7#

容器的图像大小是一个应该正确解决的问题。
有些人建议使用 alpine 分布来保存空间。
原则上这是一个很好的建议,因为有一个 alpinenodejs 镜像可以使用。
但是你必须小心,因为你必须构建所有的二进制文件。甚至 node_modules 通常只包含javascript包,在某些情况下,您必须构建二进制文件。
如果你的dockerfile现在正在工作,这不应该是你的情况,但是当你从一个 ubuntu 转移到一个不同类型的镜像时,最好记住,你将来需要使用的所有二进制文件都必须在一个 alpine 镜像中编译。
说你应该考虑你如何使用你的图像之前选择在哪里削减大小。
您的应用程序是一个单独存在于自己的容器中的应用程序,周围没有任何其他节点应用程序吗?
如果答案是否定的,你应该知道本地docker注册表中每个镜像的大小不会被计算为汇总,以获得总的使用大小。
相反,你必须在基本层中分割每个图像,并对每个uniq层求和。
我在这里的意思是,如果您有许多在节点上运行的节点应用程序,那么单个映像就不那么重要了。
您可以通过共享 node_modules 将其导出为包含所有所需依赖项的卷来保存空间。
或者更好,你可以从一个官方的 nodejs 镜像开始,创建一个中间镜像,其中包含你的应用程序的依赖项的根。例如 expressjspath。然后在每个应用程序映像中安装专用的依赖项。
因此,您可以共享公共层,从而减少本地Docker注册表的总使用大小。

次要注意事项

您不需要在容器镜像中全局安装 expresspath
你真的需要一个容器中的 vim 吗?考虑到即使在开发中修改容器也是不安全。您可以使用卷来指向服务器文件系统上的资源。或在运行时从容器中复制文件或文件夹。如果你只是想读一些东西,只需要使用像less,more或cat这样的命令。

相关问题