【问题标题】:Manage apt-get based dependency's on Docker在 Docker 上管理基于 apt-get 的依赖项
【发布时间】:2018-10-01 08:09:54
【问题描述】:

我们公司有一个基于 c++ 的大型代码,我们正在尝试迁移到基于 docker 的微服务基础架构。

我们内部有几个库可以帮助我们处理我们经常在代码中使用的辅助函数和实用程序。我们的想法是为已经安装了这个库的开发人员创建一个基础镜像,并将其用作我们的“基础”镜像。这将使我们受益于我们所有的软件始终使用我们自己库的最新版本。

我的问题与 Docker 的缓存系统与 CI 和外部依赖关系有关。假设我们有一个像这样的 Docker 文件:

FROM ubuntu:latest

# Install External dependencys
RUN apt update && apt install -y\
boost-libs \
etc...

# Copy our software
...
# Build it
...
# Install it
...

如果我们的代码更改,我们可以触发 CI,并且 docker 会理解它可以使用之前创建的缓存图像,直到它复制我们的软件。如果我们的外部依赖之一提供了更新的版本,会发生什么?缓存会自动失效吗?如果我们的任何包收到新版本,我们如何触发 CI 构建?

本质上,我们如何确保始终使用可用于外部依赖项的最新包?

请记住,上面的 Dockerfile 只是一个示例,以说明我们正在尝试使用剧本中的其他技巧,例如我们使用更轻的基础映像(不是 Ubuntu)和多阶段构建来避免生产容器中的开发包。

【问题讨论】:

  • 不,缓存的中间层不会自动失效。您有时需要从头显式重建以查看容器依赖项的更新。

标签: docker dependencies apt


【解决方案1】:

Docker 的缓存算法相当简单。它查看映像构建的先前状态以及您正在运行的命令的字符串。如果您正在执行COPYADD,它还会查看正在复制的这些文件的哈希值。如果在服务器上找到具有相同先前状态和正在运行的命令的先前构建,它将重用缓存。

这意味着外部变化,例如从外部存储库中提取包,将不会被检测到,缓存将被重用,而不是重新运行该行。我见过两种解决方案:

选项 1:通过向依赖项添加版本来更改命令。当这些依赖项之一发生更改时,您需要更新您的构建。这是额外的工作,但也保证您只提取您准备好的版本。看起来像(将 boost-libs 修复为 1.5 版本号):

# Install External dependencys
RUN apt update && apt install -y\
boost-libs=1.5 \
etc...

选项 2:更改构建参数。这些作为环境变量注入到RUN 命令中,docker 将环境中的更改视为要运行的不同命令。看起来像:

# Install External dependencys
ARG UNIQUE_VAR
RUN apt update && apt install -y\
boost-libs \
etc...

然后您可以使用以下内容构建上述内容,以触发每天在该行重新创建缓存:

docker build --build-arg "UNIQUE_VAR=$(date +%Y%m%d)" ...

请注意,您还可以随时选择不使用缓存进行构建:

docker build --no-cache ...

这将导致所有步骤(除了 from 行)的缓存都被忽略。

【讨论】:

    猜你喜欢
    • 2016-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多