在 Docker 中,apt-get install 失败并出现“无法获取 http://archive.ubuntu.com/ ... 404 Not Found”错误。为什么?我们怎样才能过去呢?

新手上路,请多包涵

我的团队使用 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 许可协议

阅读 1.3k
2 个回答

您已经声明您的 Dockerfile 包含 RUN apt-get -y update 作为它自己的 RUN 指令。但是,由于 构建缓存,如果对 Dockerfile 的所有更改都发生在文件的后面,当 docker build 运行时,Docker 将重用上次创建的中间镜像 RUN apt-get -y update 执行而不是再次运行该命令,因此任何最近添加或编辑的 apt-get install 行都将使用旧数据,从而导致您观察到的错误。

有两种方法可以解决此问题:

  1. --no-cache 选项传递给 docker build ,强制每次构建映像时运行 Dockerfile 中的每个语句。

  2. 重写 Dockerfile 以将 apt-get 命令组合在一个 RUN 指令中: RUN apt-get update && apt-get install foo bar ... 。这样,每当编辑要安装的软件包列表时, docker build 将被迫重新执行整个 RUN 指令并因此在安装之前重新运行 apt-get update

Dockerfile 最佳实践页面 实际上有 一整节关于 Dockerfiles 中的 apt-get 命令。我建议你阅读它。

原文由 jwodder 发布,翻译遵循 CC BY-SA 3.0 许可协议

问题可能与 ubuntu 资源有关

检查 /etc/apt/sources.list

如果您看到 deb http://archive.ubuntu.com/ubuntu main universe restricted multiverse ,这可能是潜在的问题。

通过用 deb http://archive.ubuntu.com/ubuntu/ trusty main universe restricted multiverse 替换它来修复它

或者它可能是镜子本身没有响应。 archive.ubuntu.com

 Name:   archive.ubuntu.com
Address: 91.189.88.152
Name:   archive.ubuntu.com
Address: 91.189.88.161
Name:   archive.ubuntu.com
Address: 91.189.88.149

用更受信任的镜像替换archive.ubuntu.com,比如 us.archive.ubuntu.com

 Name:   us.archive.ubuntu.com
Address: 91.189.91.23
Name:   us.archive.ubuntu.com
Address: 91.189.91.26


(由原始提问者编辑):

谢谢,pratek05!我的 Dockerfile 现在开始:

 FROM ubuntu:14.04
RUN sed -i'' 's/archive\.ubuntu\.com/us\.archive\.ubuntu\.com/' /etc/apt/sources.list
RUN apt-get -y update

它似乎正在工作。但由于这是一个零星的问题,只有时间会证明…

原文由 prateek05 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题