Docker Debian apt 从服务器读取错误

Docker Debian apt Error Reading from Server

apt-get 似乎在与存储库服务器的连接上出现问题。我想这可能是兼容性问题,如 here 所述,但是 apt-get clean 的建议解决方案对我不起作用。我也很惊讶,如果是这样的话,没有更多人遇到我的问题。

MWE

Dockerfile

FROM debian:jessie
RUN apt-get clean && apt-get update && apt-get install -y --no-install-recommends \
    git
$ docker build .
docker build .
Sending build context to Docker daemon 2.048 kB
Step 0 : FROM debian:jessie
---> 4a5e6db8c069
Step 1 : RUN apt-get clean && apt-get update && apt-get install -y --no-install-recommends     git
---> Running in 43b93e93feab
Get:1 http://security.debian.org jessie/updates InRelease [63.1 kB]
... some omitted ...
Get:6 http://httpredir.debian.org jessie-updates/main amd64 Packages [3614 B]
Fetched 9552 kB in 7s (1346 kB/s)
Reading package lists...
Reading package lists...
Building dependency tree...
Reading state information...
The following extra packages will be installed:
... some omitted ...
0 upgraded, 26 newly installed, 0 to remove and 0 not upgraded.
Need to get 13.2 MB of archives.
After this operation, 64.0 MB of additional disk space will be used.
Get:1 http://security.debian.org/ jessie/updates/main libgnutls-deb0-28 amd64 3.3.8-6+deb8u2 [694 kB]
... some omitted ...
Get:5 http://httpredir.debian.org/debian/ jessie/main libnettle4 amd64 2.7.1-5 [176 kB]
Err http://httpredir.debian.org/debian/ jessie/main libffi6 amd64 3.1-2+b2
  Error reading from server. Remote end closed connection [IP: 176.9.184.93 80]
... some omitted ...
Get:25 http://httpredir.debian.org/debian/ jessie/main git amd64 1:2.1.4-2.1 [3624 kB]
Fetched 13.2 MB in 10s (1307 kB/s)
E: Failed to fetch http://httpredir.debian.org/debian/pool/main/libf/libffi/libffi6_3.1-2+b2_amd64.deb  Error reading from server. Remote end closed connection [IP: 176.9.184.93 80]

E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
The command '/bin/sh -c apt-get clean && apt-get update && apt-get install -y --no-install-recommends     git' returned a non-zero code: 100

请注意,我还发布了 不同的问题。我认为它是无关的,但它很可能实际上是。

httpredir.debian.org 镜像是 "magic",因为它将对您进行负载平衡和 geo-ip,以透明地提高性能和可用性。因此,我会立即怀疑它会导致您的问题,或者至少是首先要排除的问题。

我会检查你是否可以:

  • 问题依然重现; httpredir.debian.org 将从其内部列表中删除 "bad" 个镜像,因此您的问题可能是暂时的。

  • 使用另一个非 httpredir.debian.org 镜像重现问题。尝试像 ftp.de.debian.org 这样的东西。如果它随后与此镜像一起工作,请联系 httpredir.debian.org 维护者并向他们报告问题。他们反应灵敏,对错误报告持开放态度。

我在 apt-get update 行之前将 apt-get clean 添加到我的 dockerfile 中,它似乎已经成功了。

我想我无法知道它是否是额外的命令,或者是否是运气修复了我的构建,但我听取了 https://github.com/CGAL/cgal-testsuite-dockerfiles/issues/19

的建议

对于遇到类似问题的访问者,使用 docker build 中的 --no-cache 标志可能会有所帮助。如果 apt-get 更新是旧的并且由于缓存而未被召回,则可能会发生类似的问题(尽管不是这个确切的问题)。

对于遇到此问题的任何人,这是我尝试 "fix" 通过在构建 Dockerfile 时用单个工作域换出 httpredir 来解决这个问题:

FROM debian:je...

# Insert this line before "RUN apt-get update" to dynamically
# replace httpredir.debian.org with a single working domain
# in attempt to "prevent" the "Error reading from server" error.
RUN sed -i "s/httpredir.debian.org/`curl -s -D - http://httpredir.debian.org/demo/debian/ | awk '/^Link:/ { print  }' | sed -e 's@<http://\(.*\)/debian/>;@@g'`/" /etc/apt/sources.list

# Continue with your apt-get update...
RUN apt-get update...

这个命令的作用是:

  1. curl the http://httpredir.debian.org/demo/debian/ from the building machine to get the headers from debian demo page (-s is silent, don't output. -D 是为了转储 headers)
  2. 提取headers,找到Link header片段。这包含 httpredir 推荐的最佳路线。
  3. 最后的sed -e ...就是提取出第2步link的域名
  4. 然后最后,将第 3 步中找到的域输入全局 sed 命令,并替换 /etc/apt/sources.list 中找到的域 httpredir.debian.org

这不是修复,而是一个简单的 hack 以(大大)减少构建失败的可能性。而且...如果它看起来很奇怪,请原谅我,因为这是我的原始 sed 和管道尝试。

编辑

附带说明一下,如果它选择的域太慢或没有按应有的方式响应,您可能需要通过

手动完成
  1. 访问http://httpredir.debian.org/demo.html,你应该会看到link,比如http://......./debian/。比如在写的时候看到了http://mirrors.tuna.tsinghua.edu.cn/debian/

  2. 而不是长 RUN sed -i.... 命令,而是使用此命令:

    RUN sed -i "s/httpredir.debian.org/mirrors.tuna.tsinghua.edu.cn/" /etc/apt/sources.list
    

没有足够的声誉来评论以前的答案,所以我会(令人困惑地)添加一个新答案:

  • 我不认为对单个镜像进行硬编码是真正可行的解决方案,因为例如 here,debian 实现整个 httpredir 的原因是有原因的 -- 镜像关闭或过时。
  • 我已经处理过很多次这个问题,日志总是表明 docker 实际上是 运行 apt-get 命令,这意味着 --no-cache 是不太可能修复它——只是如果你重建,httpredir 可能会选择一个不同的镜像,即使你没有改变你的 docker 文件中的任何东西,构建也会工作。

我可以通过将 -o 'Acquire::Retries=3' 添加到 apt-get install 命令来解决这个问题。

RUN apt-get update && apt-get install -o 'Acquire::Retries=3' -y git

似乎它会自动重试从另一个镜像获取包。

apt-get acquire documentation

编辑: 经过一番调查,我发现我的问题与我使用的代理服务器有关。无论如何,我都会在这里留下答案,以防对任何人有帮助。