我正在尝试在 Microsoft Azure 函数 docker 上安装一个 apt 源,这是我的 Dockerfile
FROM mcr.microsoft.com/azure-functions/python:3.0-python3.9
RUN echo 'deb [trusted=yes] http://deb.debian.org/debian testing main' > /etc/apt/sources.list.d/testing.list
RUN apt update -y
此步骤失败,apt update -y
并出现以下错误
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Get:1 http://deb.debian.org/debian buster InRelease [122 kB]
Get:2 http://security.debian.org/debian-security buster/updates InRelease [65.4 kB]
Hit:3 http://security.debian.org/debian-security jessie/updates InRelease
Get:4 http://deb.debian.org/debian buster-updates InRelease [51.9 kB]
Get:5 https://packages.microsoft.com/debian/9/prod stretch InRelease [4009 B]
Get:6 http://deb.debian.org/debian testing InRelease [112 kB]
Get:7 https://packages.microsoft.com/debian/9/prod stretch/main amd64 Packages [161 kB]
Get:8 http://deb.debian.org/debian testing/main amd64 Packages [8248 kB]
Reading package lists...
E: Repository 'http://security.debian.org/debian-security buster/updates InRelease' changed its 'Suite' value from 'stable' to 'oldstable'
E: Repository 'http://deb.debian.org/debian buster InRelease' changed its 'Suite' value from 'stable' to 'oldstable'
E: Repository 'http://deb.debian.org/debian buster-updates InRelease' changed its 'Suite' value from 'stable-updates' to 'oldstable-updates'
The command '/bin/sh -c apt update -y' returned a non-zero code: 100
但:
- 如果我在启动后运行完全相同的两个命令
docker run --rm -it --entrypoint bash mcr.microsoft.com/azure-functions/python:3.0-python3.9
,apt update -y
则运行正常, - 如果我将基础镜像更改为
debian:buster-slim
镜像所基于的镜像,docker 构建可以正常工作, - 即使命令失败,我也可以从中安装包
testing
,例如,apt update -y || apt install g++
将安装g++-10
而不是g++-8
Buster 上的默认安装。
知道命令失败的原因吗?我该如何修复它?
编辑:--allow-releaseinfo-change
在dockerfile 中添加apt update -y
可以解决这个问题,但我仍然想知道为什么没有它就失败了?
笔记:问题从 SO 移出,因为它在那里显然是题外话...如果它在这里也是题外话,请告诉我。
答案1
总结
根本问题是您使用的基础映像中的错误。永久修复方法是清除/var/lib/apt/lists
基础映像 Dockerfile,但可以通过重建基础映像或使用选项暂时解决--allow-releaseinfo-change
。
docker build
此行为在和之间不同的原因docker run -it
是使用-t
标志来分配 tty。这改变了apt -y
( APT::Get::Assume-Yes
) 的行为。
完整解释
存储库...更改了其“Suite”值
在以下情况下会发生此错误:
- APT 有一个 Release 文件的缓存版本——这就是错误。Docker 基础镜像通常应该清理这个缓存。
- 远程仓库有较新的版本
- 两个版本之间的某些字段不匹配
在非docker环境中,此项检查旨在以防止用户突然意外地安装来自不同 Debian 版本的软件包。
在这种情况下,基础镜像mcr.microsoft.com/azure-functions/python:3.0-python3.9
包含Debian buster Release 文件的缓存版本(条件 1)Suite: stable
,因为这是在建造时最新的。
然而,Debian 档案较新(条件 #2),现在有Suite: oldstable
(条件 #3),因为 Debian 10 buster 已经取代由 Debian 11 bullseye 提供。
因此,当您尝试apt update
在此基础映像上运行的时候,它会失败,因为不匹配旧缓存版本和当前版本之间。
我刚刚(2021-09-03)尝试了您的 Dockerfile,它对我来说运行良好。这可能是因为自从您发布此问题以来它已经重建。这会导致它缓存 Debian 存档中的新版本文件,从而纠正不匹配(上面的 #2/#3 不再成立)。
但是,您可以验证该错误仍然存在:
$ docker run --rm -it --entrypoint bash mcr.microsoft.com/azure-functions/python:3.0-python3.9
root@722ec78233b4:/# grep Suite /var/lib/apt/lists/*Release
/var/lib/apt/lists/deb.debian.org_debian_dists_buster-updates_InRelease:Suite: oldstable-updates
/var/lib/apt/lists/deb.debian.org_debian_dists_buster_InRelease:Suite: oldstable
/var/lib/apt/lists/packages.microsoft.com_debian_9_prod_dists_stretch_InRelease:Suite: stretch
/var/lib/apt/lists/security.debian.org_debian-security_dists_buster_updates_InRelease:Suite: oldstable
/var/lib/apt/lists/security.debian.org_debian-security_dists_jessie_updates_InRelease:Suite: oldoldstable
oldoldstable
在下一个 Debian 版本发布后,当 buster 变成,bullseye 变成时,相同的错误将再次出现oldstable
。
我最近在一个不相关的docker基础镜像上看到了类似的问题,我认为这个错误相当普遍。
-y
期权行为
当您apt
使用 tty 作为 stdin 运行时,-y
将覆盖此检查并允许update
命令成功。但是,如果没有 tty(非交互式会话),则-y
选项不会覆盖此项检查。我使用旧版本的错误图像确认了这一点:
# aborts
docker run --rm mcr.microsoft.com/azure-functions/python:3.0.15066-python3.9-slim apt update -y
# succeeds
docker run -t --rm mcr.microsoft.com/azure-functions/python:3.0.15066-python3.9-slim apt update -y
# prompts for y/N to continue
docker run -it --rm mcr.microsoft.com/azure-functions/python:3.0.15066-python3.9-slim apt update
# aborts
docker run --rm mcr.microsoft.com/azure-functions/python:3.0.15066-python3.9-slim apt update