【问题标题】:Docker: is it possible not to build from scratch w/o using cache?Docker:是否可以不使用缓存从头开始构建?
【发布时间】:2019-08-30 13:29:15
【问题描述】:

我有一个简单的 Docker 文件:

FROM python:3.6
COPY . /app
WORKDIR /app
RUN pip install -r requirements

问题是 - 它会在每个构建中安装要求。我有很多要求,但它们很少改变。

我搜索了解决方案并最终得到了这个:

FROM python:3.6
COPY requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip install -r requirements.txt
COPY . /app

效果很好,直到它停止更新代码。例如,在 /app 和 build 的某些文件中注释几行 - 行在图像中保持未注释。

我再次搜索,发现这可能是缓存引起的。我尝试了 --no-cache 构建标志,但现在我又开始安装需求了。

在我的情况下是否有一些解决方法或正确的方法?

【问题讨论】:

  • 你使用什么命令来构建和运行镜像?您如何看待您的更改没有产生效果?
  • 我不确定 pip 在这个意义上是如何工作的,但是如果它只能以某种方式下载特定版本的依赖项,那么您可以手动预先准备它们,在 docker 文件中只需将内容复制到请求的位置- 如果它是独立的 - 此外,您仍然可以安装一些额外的 dep。由于某种原因,每个版本仍然需要下载它。可能是?例如。与maven相比,它会“只下载一些jar”,所以你可以手动下载然后复制。所以你可以只改变一小层图像。
  • @DavidMaze 场景查看文件未更改:1) docker build -t 。 2) docker run --rm -ti bash 3) cat /app/filename
  • @xxxvodnikxxx 猜测考虑到 SiHa 的回答,这可能是解决方法
  • @Mikekekeke 我不这么认为,在需求文件中我发现您还需要以静态方式指定版本,所以基本上,它是一个静态内容(就版本而言),那么,您可以交付手动复制它们。在 docker 的这个意义上,它可以与缓存一起工作,所以你不需要每次都重建所有层,而只需要重建被改变的层。如果您不使用副本更改图层,那么我认为应该更快地构建它:) 至少在理论上..

标签: docker docker-build


【解决方案1】:

如果你想使缓存失效,你应该使用ADD 而不是COPY

FROM python:3.6
COPY requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip install -r requirements.txt
ADD . /app

试试上面的 docker 文件。

【讨论】:

  • ADDCOPYthe build cache 方面是相同的。唯一的区别是ADD 将自行执行 HTTP GET 并解压缩档案。通常你应该更喜欢COPY,除非你特别想要那种行为。
  • 你是对的,再次阅读文档肯定似乎是这样说的。让我去尝试一下
【解决方案2】:

你用过 docker-compose 吗? Docker-compose 有“卷”,它作为缓存,当你启动容器时,它不会重新构建你的依赖项。当您的代码更改时,它会自动刷新。 根据您的情况,您应该这样做:

FROM python:3.6
WORKDIR /app
COPY . /app
COPY requirements.txt ./
RUN pip install -r requirements.txt
CMD["python","app.py"]

让我们试试。

【讨论】:

  • 我正在处理的项目中的当前工作流程不包括 docker-compose。现在它只是“构建映像 -> 部署到 kubernetes 集群”
  • 你做到了吗?您应该通过以下命令构建映像并推送到 docker hub: docker build --tag your_acc/image:tag 然后“标记”并推送到 docker hub。然后将它与 Kubernetes 一起使用
  • 这正是我正在做的。但是我可以检查图像中的文件是否是最新的,而无需将它们推送到集线器。我还没有尝试你建议的 docker 文件,但是
  • 你可以通过命令访问容器:"docker run -it your_image bash" 来检查你的文件。
【解决方案3】:

Docker 不会看到更改您只是复制到 (COPY . /app) 中的文件,因此它将使用缓存层 *,因此是您的结果。使用--no-cache 将强制重新构建每一层,再次解释您观察到的内容。

避免每次都重新安装所有要求的“docker”方法是将所有静态要求放在基础映像中,然后在您的FROM 行中使用此映像以及所有其他更改的要求。


* 虽然,我很确定我已经观察到,如果您复制命名文件而不是目录,即使没有 --no-cache子>

【讨论】:

  • 文件的实际内容应该用来决定是否使用the cache(见第三个要点)。
猜你喜欢
  • 2019-03-09
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 2018-06-27
  • 2011-05-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多