我的团队使用 Docker(带有 ubuntu:14.04
基础镜像)进行本地开发,我们经常需要重建部分或全部镜像。但是我们经常在下载带有 apt-get install
的软件包时遇到失败,即使在运行之后立即 apt-get -y update
。例如,今天我看到
Err http://archive.ubuntu.com/ubuntu/ trusty-security/main libxml2 amd64 2.9.1+dfsg1-3ubuntu4.7
404 Not Found [IP: 91.189.88.161 80]
Err http://archive.ubuntu.com/ubuntu/ trusty-security/main libxml2-dev amd64 2.9.1+dfsg1-3ubuntu4.7
404 Not Found [IP: 91.189.88.161 80]
Fetched 84.7 MB in 1min 6s (1281 kB/s)
Unable to correct missing packages.
E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/libx/libxml2/libxml2_2.9.1+dfsg1-3ubuntu4.7_amd64.deb 404 Not Found [IP: 91.189.88.161 80]
E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/libx/libxml2/libxml2-dev_2.9.1+dfsg1-3ubuntu4.7_amd64.deb 404 Not Found [IP: 91.189.88.161 80]
E: Aborting install.
显然,特定软件包的特定版本已从存档中删除,并替换为名称略有不同的补丁版本。例如,上述错误正在寻找 libxml2_2.9.1+dfsg1-3ubuntu4.7_amd64.deb
但服务器上的版本是 libxml2_2.9.1+dfsg1-3ubuntu4.8_amd64.deb
。
这通常可以通过删除基础映像( docker rmi ubuntu:14.04
)并重建来解决;新下载的 ubuntu 映像具有正确的补丁号并找到正确的存档文件。但即使这样也并不总是有效——可能是由于对 Ubuntu 的依赖数据库进行新的小升级和将新的 ubuntu:14.04
映像部署到 Docker Hub 之间存在延迟。
我们已经尝试使用 apt-get
标志 --fix-missing
和 --fix-broken
并且这些也不能始终有效。
还有其他想法吗?
apt-get install 失败并出现 Not Found 错误,因为从存储库中删除的包 是一个类似的问题,但接受的答案是不可接受的,因为它不可能自动化。我们的日常开发过程,包括自动构建和部署,都是脚本化的并且使用 Docker,每次特定存档丢失时在 Dockerfile 中进行破解是不切实际的(然后在几个小时或几天后删除破解)。
回应@prateek05,这里是来自官方的 /etc/apt/sources.list
ubuntu:14.04
镜像:
root@72daa1942714:/# cat /etc/apt/sources.list
# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://archive.ubuntu.com/ubuntu/ trusty main restricted
deb-src http://archive.ubuntu.com/ubuntu/ trusty main restricted
## Major bug fix updates produced after the final release of the
## distribution.
deb http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted
deb-src http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted
## Uncomment the following two lines to add software from the 'universe'
## repository.
## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team. Also, please note that software in universe WILL NOT receive any
## review or updates from the Ubuntu security team.
deb http://archive.ubuntu.com/ubuntu/ trusty universe
deb-src http://archive.ubuntu.com/ubuntu/ trusty universe
deb http://archive.ubuntu.com/ubuntu/ trusty-updates universe
deb-src http://archive.ubuntu.com/ubuntu/ trusty-updates universe
## N.B. software from this repository may not have been tested as
## extensively as that contained in the main release, although it includes
## newer versions of some applications which may provide useful features.
## Also, please note that software in backports WILL NOT receive any review
## or updates from the Ubuntu security team.
# deb http://archive.ubuntu.com/ubuntu/ trusty-backports main restricted
# deb-src http://archive.ubuntu.com/ubuntu/ trusty-backports main restricted
deb http://archive.ubuntu.com/ubuntu/ trusty-security main restricted
deb-src http://archive.ubuntu.com/ubuntu/ trusty-security main restricted
deb http://archive.ubuntu.com/ubuntu/ trusty-security universe
deb-src http://archive.ubuntu.com/ubuntu/ trusty-security universe
# deb http://archive.ubuntu.com/ubuntu/ trusty-security multiverse
# deb-src http://archive.ubuntu.com/ubuntu/ trusty-security multiverse
原文由 AlexChaffee 发布,翻译遵循 CC BY-SA 4.0 许可协议
您已经声明您的 Dockerfile 包含
RUN apt-get -y update
作为它自己的RUN
指令。但是,由于 构建缓存,如果对 Dockerfile 的所有更改都发生在文件的后面,当docker build
运行时,Docker 将重用上次创建的中间镜像RUN apt-get -y update
执行而不是再次运行该命令,因此任何最近添加或编辑的apt-get install
行都将使用旧数据,从而导致您观察到的错误。有两种方法可以解决此问题:
将
--no-cache
选项传递给docker build
,强制每次构建映像时运行 Dockerfile 中的每个语句。重写 Dockerfile 以将
apt-get
命令组合在一个RUN
指令中:RUN apt-get update && apt-get install foo bar ...
。这样,每当编辑要安装的软件包列表时,docker build
将被迫重新执行整个RUN
指令并因此在安装之前重新运行apt-get update
Dockerfile 最佳实践页面 实际上有 一整节关于 Dockerfiles 中的
apt-get
命令。我建议你阅读它。