如何减小Docker镜像的大小

时间:2017-04-26 12:22:46

标签: docker docker-compose dockerfile

我有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中的某些内容以减少泊坞窗图像大小

7 个答案:

答案 0 :(得分:6)

使用the official node alpine image作为基本图像,正如此处大多数建议的那样,是一种简单的解决方案,可以减小图像的整体尺寸,因为即使是基本的高山图像也比基本的ubuntu图像要小得多。 / p>

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图像的大多数命令都可以在高山图像中以相同的方式应用。

当我添加模拟数据以创建一个类似的项目时,会产生一个大小为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

答案 1 :(得分:3)

尝试将所有RUN条指令打包在一起,它会减少中间图像的数量。 (但它不会减小尺寸)。

rm -rf /var/lib/apt/lists/*之后添加apt-get update会删除所有无用的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 ]

答案 2 :(得分:2)

1)搬到阿尔卑斯山可能是最好的选择。我刚刚将一个Ubuntu docker文件移植到Alpine,从1.5GB移动到585MB。我跟着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)您可能还对multi-stage build感兴趣,其中您只需将必要的组件复制到最终图像。

答案 3 :(得分:1)

第一步生成的图像,别名:builder

将第一步图像的乘积复制到当前图像,仅使用一个图像层,从而节省上一步的图像层数。

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"]

答案 4 :(得分:0)

如果您基于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来安装它,它将被缓存而不会在下一个构建中被触发。

答案 5 :(得分:0)

容器的图像大小是一个应该正确解决的问题。

有人建议使用 alpline 发行版来节省空间。

原则上这是一个很好的建议,因为 alpine nodejs 图像已准备好使用。

但是你必须要小心,因为你必须构建所有的二进制文件。甚至_node_modules_通常只包含javascript包,在某些情况下你必须构建二进制文件。

如果您的dockerfile现在正在运行,那么情况应该不是这样,但是当您从 ubuntu 转移到另一种类型的图像时,最好记住所有二进制文件你需要在将来使用必须在 alpine 图像中编译。

说在选择切割尺寸的位置之前,你应该考虑如何使用你的图像。

您的应用程序是否是一个单独的应用程序,只在一个自己的容器中,没有任何其他节点应用程序?

如果答案为否,您应该知道本地docker注册表中每个图像的大小不计入摘要以获得总使用大小。

相反,您必须在基本图层中分割每个图像并对每个uniq图层求和。

我的意思是,如果您有许多在节点上运行的节点应用,那么单个图像就不那么重要了。

您可以通过共享_node_modules_来节省空间,将其导出为包含所有必需依赖项的卷。

或者更好的是,您可以从官方的 nodejs 图像开始创建一个包含应用程序依赖关系根的中间图像。例如 expressjs 路径。然后在每个应用程序映像中安装专用依赖项。

因此,您可以获得共享图层的优势,从而减少本地docker注册表的总使用大小。

次要注意事项

您无需在容器图片中全局安装 express 路径

你真的需要在容器中使用 vim 吗? 考虑到即使在开发过程中修改容器也不安全。您可以使用该卷指向服务器文件系统上的资源。 或者在运行时从容器中复制进/出文件或文件夹。 如果您只是需要阅读某些内容,只需使用less,more或cat等命令。

答案 6 :(得分:0)

考虑使用此方法: --no-install-recommends安装软件包时,请考虑使用apt-get。这将导致较小的图像尺寸。有关更多信息,请参阅此博客文章

有一个不错的博客,告诉您一些减少图像大小的步骤。

减少Docker映像大小的提示 https://hackernoon.com/tips-to-reduce-docker-image-sizes-876095da3b34