所以我知道每个RUN
命令docker都会创建一个层,或者如果你愿意的话会威胁图像,这会导致缓存apt-get update
。但我在docker中安装新软件包时遇到了非常困难apt-get
,我不确定发生了什么,我花了几个小时四处寻找却一无所获,我主要使用ubuntu作为基础图像。
某些软件包似乎会随机无法安装,例如 wget。如果我进入容器中的终端,然后执行,apt-get update
我apt-get install wget
可以安装 wget。但在 docker 文件中,即使我删除每个 RUN 行创建的所有映像以停止缓存更新,我也无法使用完全相同的命令安装 wget,这太疯狂了,我感觉自己快要疯了。
其他软件包似乎随机地工作或不工作。我甚至有这个软件包:python-glpk
它最初安装在 Dockerfile 中,但现在不再安装了...我无法看到任何确定性的更新和安装行为,它们似乎只在风向某个方向吹的时候才工作。
使用互联网进行更新需要很长时间,而且我在虚拟机上,所以我的工作流程完全中断,浪费了这么多时间,还有其他人遇到简单的问题吗apt-get update && apt-get install
?在 docker 中处理时的最佳做法是什么,apt-get
以确保一切正常运行?
答案1
只是关于这个话题的一个好奇的注释。一些人倾向于自定义FROM ubuntu
和添加帮助脚本来修剪软件包安装。但官方的 ubuntu:18.04 映像有一些改进。运行此命令:
docker run --rm -it ubuntu:18.04 bash
环顾四周,/etc/apt
你会发现它有几个专门用于 docker 构建的触发器。
root@12711b0547f3:/# ll /etc/apt/apt.conf.d/
total 40
drwxr-xr-x 1 root root 4096 Feb 6 03:37 ./
drwxr-xr-x 1 root root 4096 Feb 4 21:03 ../
-rw-r--r-- 1 root root 42 Apr 20 2018 01-vendor-ubuntu
-rw-r--r-- 1 root root 927 Jan 25 11:51 01autoremove
-r--r--r-- 1 root root 1081 Feb 4 21:03 01autoremove-kernels
-rw-r--r-- 1 root root 182 Feb 28 2018 70debconf
-rw-r--r-- 1 root root 44 Feb 6 03:37 docker-autoremove-suggests
-rw-r--r-- 1 root root 318 Feb 6 03:37 docker-clean
-rw-r--r-- 1 root root 70 Feb 6 03:37 docker-gzip-indexes
-rw-r--r-- 1 root root 27 Feb 6 03:37 docker-no-languages
apt
已预先配置为每次清除缓存apt install
、使用压缩索引以及避免建议任何进一步的包。
答案2
一些输出或日志可以很好地回答您的问题。
有时apt-get 更新速度越来越慢,这与 docker 本身无关。如果连接不好,软件包可能无法完全下载。
正如您所说,Dockerfile 中的每一行都会创建一个镜像层,并且缓存将保存在本地,以加快镜像创建速度。有一些做法可以通过合并来最小化 docker 镜像大小,并尽可能少地放置行,因此在软件包安装的情况下使用以下模式:
RUN \
apt-get update &&\
apt-get install -y zip &&\
rm -rf /var/lib/apt/lists/*
这将需要一些时间来更新缓存、安装包和清理空间,并且它将只生成单个图像层,因此您需要安装任何其他包apt-get 更新首先安装软件包。
您可以尝试的一种方法是在新的 RUN 语句中运行每个步骤:
RUN \
apt-get update
RUN \
apt-get install -y zip
RUN \
apt-get install -y curl
这样,您将拥有更多层,但将具有“更新”的 apt 缓存层,并将逐个安装软件包。