在Docker中,apt-get安装失败,“无法获取http://archive.ubuntu.com/ … 404 Not Found”错误。 为什么? 我们怎么能通过它?

我的团队使用Docker(与ubuntu:14.04基础图像)本地开发,我们经常不得不重build我们的一些或全部图像。 但是我们经常会在使用apt-get install下载软件包时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. 

显然,特定软件包的特定版本已经从存档中删除,并被replace为稍微不同的补丁版本。 例如,上面的错误是查找libxml2_2.9.1+dfsg1-3ubuntu4.7_amd64.deb但服务器上的版本是libxml2_2.9.1+dfsg1-3ubuntu4.8_amd64.deb

通常这是通过删除基础镜像( docker rmi ubuntu:14.04 )和重build来解决的; 新下载的Ubuntu镜像有正确的补丁号码,并find正确的归档文件。 但是,即使这样也并不总是奏效的 – 可能是由于Ubuntu的依赖数据库的一次新的小升级和将新的ubuntu:14.04映像部署到Docker Hub上之间的延迟。

我们已经试过使用apt-get标志 – --fix-missing和 – --fix-broken ,这些不一致的工作。

任何其他的想法?

apt-get安装失败,发现错误,因为从存储库中删除的包是一个类似的问题,但接受的答案是不可接受的,因为它不可能被自动化。 我们的日常开发过程,包括自动构build和部署,都是脚本化的,使用Docker,每当特定的档案丢失(然后在几个小时或几天后删除破解),在Dockerfile内部进行破解是不切实际的。


作为对@ prateek05的回应,这里是官方ubuntu:14.04上的/etc/apt/sources.list docker image:

 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. ## NB 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 ## NB 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 

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

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

  1. --no-cache选项传递给docker 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命令的完整部分 。 我建议你阅读它。

这个问题可能与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 

(由oiriginal asker编辑):

谢谢,prateek05! 我的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 

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

使用FTP源工作100%的时间。

 RUN echo \ 'deb ftp://ftp.us.debian.org/debian/ jessie main\n \ deb ftp://ftp.us.debian.org/debian/ jessie-updates main\n \ deb http://security.debian.org jessie/updates main\n' \ > /etc/apt/sources.list