ubuntu - 在 docker 中卸载应用程序?

标签 ubuntu docker apt-get

我正在使用 docker 来构建和运行一组服务。对于其中一个,我需要安装一些包以完成内部(gulp.js)构建过程,但在最终的 docker 镜像中它们不是必需的。似乎我应该在构建 docker 镜像时卸载它们,以保持镜像更小。有这方面的标准做法吗?

相关:Docker 图像的合理大小是多少?我意识到“合理”是主观的,但是 1.4 GB 听起来很疯狂吗?

这是我现在存在的 Dockerfile:

FROM python:3.5.1-onbuild
ARG mode=dev

ENV MODE $mode

RUN apt-get update && apt-get install -y \
  build-essential \
  curl \
  && rm -rf /var/lib/apt/lists/*
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash
RUN apt-get install -y nodejs
RUN cd $(npm root -g)/npm \
  && npm install fs-extra \
  && sed -i -e s/graceful-fs/fs-extra/ -e s/fs\.rename/fs.move/ ./lib/utils/rename.js


WORKDIR /usr/src/app/app
RUN npm install
RUN npm install --global gulp-cli
RUN npm rebuild node-sass
RUN gulp
RUN rm -rf node_modules

WORKDIR /usr/src/app
EXPOSE 8080
RUN python3 setup.py install
CMD python3 manage.py ${MODE}

最佳答案

Docker 镜像使用分层文件系统。 Dockerfile 中的每个语句将导致一个新层被添加到生成的图像中。您可以使用 docker history 检查这些层。命令。

在构建步骤中删除包不会减少整体镜像大小,因为删除的文件仍将存在于父层中(尽管这些文件将被标记为已删除并且在您从此镜像创建容器时不存在)。

例子

考虑一个简短的例子:

FROM debian:8
RUN dd if=/dev/zero of=/tmp/test bs=1024 count=100K
RUN rm /tmp/test

这个例子Dockerfile在第一个 RUN 中创建一个包含 100 MiB 文件的图像声明并在第二个 RUN 中删除它陈述。现在使用 docker history <image-id> 检查创建的图像:
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
02b8c1077ac1        8 seconds ago       /bin/sh -c rm /tmp/test                         0 B                 
64a98e72b7ca        8 seconds ago       /bin/sh -c dd if=/dev/zero of=/tmp/test bs=10   104.9 MB            
737e719de6a4        4 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0 B                 
1f2a121fc3e4        4 weeks ago         /bin/sh -c #(nop) ADD file:41ea5187c50116884c   123 MB      

如您所见,100MiB 层仍然存在。生成的图像总大小约为 200MB:
REPOSITORY         TAG      IMAGE ID            CREATED             VIRTUAL SIZE
<none>             <none>   02b8c1077ac1        8 minutes ago       227.9 MB

怎么修

我看到了两种减小图像大小的可能性:
  • 确保您的 npm install命令和随后的 rm -rf node_modules在相同的构建步骤中运行:
    RUN npm install && \
        npm install --global gulp-cli && \
        npm rebuild node-sass && \
        gulp && \
        rm -rf node_modules
    

    此语句将仅在生成的镜像中创建单个文件系统层,没有 node_modules目录。
  • 将图像层“压缩”为一个。像 docker-squash 这样的工具可能对此有所帮助。请注意,压缩图像层会使(通常非常有效)docker pushdocker pull操作效率较低。通常,这些操作只传输本地(当 pull 时)或远程(当 push 时)端不存在的图像的特定层。当您的图像仅包含一层时,docker pushpull将始终传输整个图像。
  • 关于ubuntu - 在 docker 中卸载应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41068136/

    相关文章:

    ubuntu - 在 ubuntu 上安装 Docker

    docker - 安装 Couchbase 的特定 docker 镜像

    apt-get - Bash - 如果 apt-get/dpkg 正在运行,如何检查是否可以安装软件包?

    node.js - 通过 apt-get 安装的 NodeJS 最新版本

    ubuntu - fltk cmake ubuntu 链接错误

    docker - 通过 Docker 客户端从主机连接到 Vagrant VM 中的 Docker Daemon

    适用于 Ubuntu 的 Java NFC 标签应用程序

    performance - MongoDB Ubuntu 安装需要几个小时

    docker - 在 ubuntu 中运行不带 sudo 的 docker

    postgresql - 允许任何用户以完全权限连接到 postgres 吗?