Alpine Dockerfile中--no-cache与rm /var/cache/apk/*的优势对比。

198
当使用Alpine镜像创建Dockerfiles时,我经常看到两种用法:
1. 使用apk add --no-cache命令; 2. 使用apk add命令,然后跟上rm /var/cache/apk/*语句。
我很好奇使用--no-cache标志是否能够省去手动清除软件包缓存的步骤(即rm /var/cache/apk/*)。我也想知道哪种方式被认为是最佳实践。

15
我的理解是,--no-cache 的作用是让你之后不需要执行 rm /var/cache/apk/* - Javier Buzzi
2
作为更新,现在使用Buildkit,您可以让您的APK等缓存自由运行,而无需重复下载或通过将这些缓存挂载到主机来增加镜像大小,使用RUN --mount=type=cache...apt示例在此处 - esmail
1
任何新来者都应该看看@esmail的评论,它真的让你既能吃蛋糕又能拥有它。文档也已更新,包括有关此主题的信息:https://docs.docker.com/build/building/cache/#use-the-dedicated-run-cache - gustafc
2个回答

284

--no-cache选项允许不在本地缓存索引,这对于保持容器小型很有用。

从字面上讲,它等同于开始时运行apk update,结束时运行rm -rf /var/cache/apk/*

以下是一些使用--no-cache选项的示例:

$ docker run -ti alpine:3.7
/ # apk add nginx
WARNING: Ignoring APKINDEX.70c88391.tar.gz: No such file or directory
WARNING: Ignoring APKINDEX.5022a8a2.tar.gz: No such file or directory
ERROR: unsatisfiable constraints:
  nginx (missing):
    required by: world[nginx]
/ # 
/ # apk add --no-cache nginx
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
(1/2) Installing pcre (8.41-r1)
(2/2) Installing nginx (1.12.2-r3)
Executing nginx-1.12.2-r3.pre-install
Executing busybox-1.27.2-r7.trigger
OK: 6 MiB in 13 packages
/ # 
/ # ls -la /var/cache/apk/
total 8
drwxr-xr-x    2 root     root          4096 Jan  9 19:37 .
drwxr-xr-x    5 root     root          4096 Mar  5 20:29 ..

另一个我们不使用--no-cache选项的示例:

$ docker run -ti alpine:3.7
/ # apk add nginx
WARNING: Ignoring APKINDEX.70c88391.tar.gz: No such file or directory
WARNING: Ignoring APKINDEX.5022a8a2.tar.gz: No such file or directory
ERROR: unsatisfiable constraints:
  nginx (missing):
    required by: world[nginx]
/ # 
/ # apk update
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
v3.7.0-107-g15dd6b8ab3 [http://dl-cdn.alpinelinux.org/alpine/v3.7/main]
v3.7.0-105-g4b8b158c40 [http://dl-cdn.alpinelinux.org/alpine/v3.7/community]
OK: 9048 distinct packages available
/ # 
/ # apk add nginx
(1/2) Installing pcre (8.41-r1)
(2/2) Installing nginx (1.12.2-r3)
Executing nginx-1.12.2-r3.pre-install
Executing busybox-1.27.2-r7.trigger
OK: 6 MiB in 13 packages
/ # 
/ # ls -la /var/cache/apk/
total 1204
drwxr-xr-x    2 root     root          4096 Mar  5 20:31 .
drwxr-xr-x    6 root     root          4096 Mar  5 20:31 ..
-rw-r--r--    1 root     root        451508 Mar  3 00:30 APKINDEX.5022a8a2.tar.gz
-rw-r--r--    1 root     root        768680 Mar  5 09:39 APKINDEX.70c88391.tar.gz
/ # 
/ # rm -vrf /var/cache/apk/*
removed '/var/cache/apk/APKINDEX.5022a8a2.tar.gz'
removed '/var/cache/apk/APKINDEX.70c88391.tar.gz'

你可以看到两种情况都是有效的。对我来说,使用--no-cache选项更为优雅。


41
我认为使用--no-cache更好。但如果有多个apk add --no-cache命令,索引文件会每次都重新下载。在这种情况下,最好在顶部执行apk update,然后在底部执行rm -rf /var/cache/apk/*以减少网络流量。当某些软件包使用 --virtual 添加时,这一点非常重要。 - lilole
8
你能否将多个"apk add"命令合并成一个命令? - Paul Calabro
1
@PaulCalabro 在我的工作中,我们的Dockerfiles总是使用单个apk add。但是--virtual选项非常方便,并且在多个apk add调用时真正发挥作用。然而,从长远来看,在--virtual真正为我们带来好处之前,我们可能会转向多阶段Dockerfiles。 - lilole
1
如果我在Debian镜像上使用apt-get,那么“--no-cache”的等效选项是什么? - Vikas Prasad
17
@lilole的建议有一个主要问题,即当作为单独的Dockerfile "RUN"语句运行时,“rm -rf ...”不会减小镜像大小。您必须在同一运行语句中执行它,否则缓存将被嵌入镜像层中,尽管在最终镜像中无法访问。 - Philip Couling
1
没错,这是真的,通常的层大小优化总是适用的:在每组RUN命令中尽可能地从每个层中删除尽可能多的内容。 - lilole

7

1
APK清单非常高效,我认为共享缓存的努力不值得,特别是因为您必须每次更新缓存以获取最新版本。在Docker中干脆不要缓存。 - erik258
如果您正在使用Docker,最好在每个apk add命令中使用no-cache选项,而不是在最后使用。如果您有一个单一的安装包可以安装所有需要的内容,则更好,以避免创建Docker层。 - c4f4t0r

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接