【问题标题】:speeding up 'apt-get update' to speed up Docker image builds加快 'apt-get update' 以加快 Docker 映像构建
【发布时间】:2019-05-14 23:01:49
【问题描述】:

我想将curl 添加到 Docker 映像中,并且我在 Dockerfile 中使用以下命令来执行此操作:

RUN apt-get update
RUN apt-get install curl ca-certificates -y

我的问题是初始更新需要很长时间才能运行(2 分钟),所以当我调试 Dockerfile 时,迭代速度很慢。特别是当我在RUN apt-get update 之前进行更改时,这会使 Docker 的图像缓存无效。

有什么方法可以让apt-get update 更有选择性,所以它只更新到足以索引下载curl 的位置?或者我可以使用其他一些技术来加快我的 Docker 构建速度?

这是整个 Dockerfile,

FROM postgres:9.6.10
ADD data/tsvs.tar.gz /standard_data
COPY postgres/*.sql /docker-entrypoint-initdb.d/

RUN apt-get update
RUN apt-get install curl ca-certificates -y
RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
RUN apt-get install postgis postgresql-9.6-postgis-scripts -y

我目前正在更改 postgres/*.sql 中的 SQL 文件,因此缓存失效。

【问题讨论】:

  • 你能给我们整个 Dockerfile 吗?可能有一些方法可以利用 Docker 缓存。

标签: docker apt


【解决方案1】:

图像是按层组织的,每一层都依赖于前一层。图层也被缓存以提高速度。

当您再次运行构建时,请继续检查 dockerfile 中命令行的校验和是否更改。如果没有,那么它将从缓存中提取图层。但如果这样做了,那么它会重建后面的所有后续层。

在您的特定情况下,每次您进行更改时,ADD 命令都会生成一个新层,并触发所有后续层的重建。

在解决此问题之前移动安装。

您还应该将所有安装放在 1 行,并在完成后清理 apt 缓存。

RUN apt-get install curl ca-certificates -y && \
  curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \
  apt-get install postgis postgresql-9.6-postgis-scripts -y && \
  rm -rf /var/cache/apt && \
  apt-get clean

【讨论】:

  • 请注意,如果您使用 multi-stage builds 简单地复制您感兴趣的构建工件,则可能不需要在 apt 之后进行清理。
【解决方案2】:

如果我将 curl 安装内容移动到我正在更改的部分之前,缓存将更频繁地命中。我的新文件是

FROM postgres:9.6.10
RUN apt-get update
RUN apt-get install curl ca-certificates -y
RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
RUN apt-get install postgis postgresql-9.6-postgis-scripts -y

ADD data/tsvs.tar.gz /standard_data
COPY postgres/*.sql /docker-entrypoint-initdb.d/
COPY postgres/subsetting.s* /docker-entrypoint-initdb.d/

感谢 Caleb H. 在他的评论中考虑到这一点。

【讨论】:

  • 请注意:在同一 RUN 中没有所有 apt-* 命令是 docker 反模式。详情请看:runnable.com/blog/9-common-dockerfile-mistakes
  • 如果替代方案在非平凡的情况下非常难以做到,这不是反模式,例如在生成的 Dockerfile 中,从多个组件组装所需的功能,每个组件都需要安装自己的依赖项。
  • @SzczepanHołyszewski 在这种情况下我们可能会使用多阶段构建,我猜?
  • @ziuyang 不。apt-*命令在安装包时所做的工作是很重要的,所有这些都必须在最终映像中安装包时完成,以确保它是安装正确,没有任何遗漏。 “安装在中间,哑副本到最终版本”会导致问题。那是反模式。可以在中间从源代码构建,生成一个包,然后使用适当的安装工具在最终安装,但使用后者是不可避免的。
【解决方案3】:

This post on reddit 建议将本地 apt sources.list 复制到带有 COPY sources.list /etc/apt/ 的容器可能有助于容器的 apt update 使用本地镜像,这可能会加快速度

【讨论】:

    猜你喜欢
    • 2020-09-27
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多