问题描述
我的团队使用Docker(带有ubuntu:14.04
基本映像)进行本地开发,我们经常需要重建部分或全部图像。但是,即使在运行apt-get -y update
之后,我们也常常无法使用apt-get install
下载软件包。例如,今天我看到了
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 fails with Not Found error because package removed from repository是一个类似的问题,但接受的答案是不可接受的,因为它不可能自动化。我们的日常开发过程,包括自动构建和部署,都是使用Docker编写脚本的,每次特定存档丢失时(在几小时或几天后删除hack),在Dockerfile内部进行黑客攻击是不切实际的。
在回复@ prateek05时,这是来自官方ubuntu:14.04
泊坞窗图像的/etc/apt/sources.list
:
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
最佳解决方法
您已声明您的Dockerfile包含RUN apt-get -y update
作为其自己的RUN
指令。但是,由于build caching,如果Dockerfile的所有更改都发生在文件的后面,那么当运行docker build
时,Docker将重用上次执行RUN apt-get -y update
时创建的中间映像,而不是再次运行命令,因此任何recently-added或编辑的apt-get install
行将使用旧数据,导致您观察到的错误。
有两种方法可以解决这个问题:
-
将
--no-cache
选项传递给docker build
,强制每次构建映像时都运行Dockerfile中的每个语句。 -
重写Dockerfile以在单个
RUN
指令中组合apt-get
命令:RUN apt-get update && apt-get install foo bar ...
。这样,每当编辑要安装的软件包列表时,docker build
将被强制为re-execute整个RUN
指令,因此在安装之前重新运行apt-get update
。
Dockerfile best practices page实际上有一个关于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
(由原始提问者编辑):
谢谢,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
它似乎工作。但由于这是一个零星的问题,只有时间会告诉……