Dockerfile: 如何根据Ubuntu版本设置apt镜像

3

在构建Docker镜像时,可以通过覆盖/etc/apt/sources.list来设置自定义的apt镜像,例如:

FROM ubuntu:focal

RUN echo "deb mirror://mirrors.ubuntu.com/mirrors.txt focal main restricted universe multiverse" > /etc/apt/sources.list && \
    echo "deb mirror://mirrors.ubuntu.com/mirrors.txt focal-updates main restricted universe multiverse" >> /etc/apt/sources.list && \
    echo "deb mirror://mirrors.ubuntu.com/mirrors.txt focal-security main restricted universe multiverse" >> /etc/apt/sources.list
...

如果基础镜像是一个变量,例如FROM ${DISTRO},则应根据Ubuntu版本调整sources.list

我尝试了以下命令:$(lsb_release -cs)

RUN echo "deb mirror://mirrors.ubuntu.com/mirrors.txt $(lsb_release -cs) main restricted universe multiverse" > /etc/apt/sources.list && \
    echo "deb mirror://mirrors.ubuntu.com/mirrors.txt $(lsb_release -cs)-updates main restricted universe multiverse" >> /etc/apt/sources.list && \
    echo "deb mirror://mirrors.ubuntu.com/mirrors.txt $(lsb_release -cs)-security main restricted universe multiverse" >> /etc/apt/sources.list

但是它提示 lsb_release: not found

解决方法是在运行之前安装这个包。

RUN apt-get update && apt-get install -y lsb-release

然而,在某些地区,安装lsb-release包可能非常缓慢。

因此问题是,有没有一种适当的方法在使用apt之前设置apt源镜像呢?

3个回答

10

可以利用sed直接编辑现有的sources.list文件。以下代码片段将不考虑确切的发行版在原地修改源文件(并且在其他基于Debian的发行版上运行时也是安全的,但不会修改那里的文件)。

它将/etc/apt/sources.list文件中所有指向http://archive.ubuntu.com/ubuntu的引用更改为mirror://mirrors.ubuntu.com/mirrors.txt(告诉内置的apt客户端在从网络获取内容时自动使用本地镜像),即可实现修改。

sed -i -e 's/http:\/\/archive\.ubuntu\.com\/ubuntu\//mirror:\/\/mirrors\.ubuntu\.com\/mirrors\.txt/' /etc/apt/sources.list

如果要在 Dockerfile 中使用,只需在尽可能早的位置,像这样运行:RUN

RUN sed -i -e 's/http:\/\/archive\.ubuntu\.com\/ubuntu\//mirror:\/\/mirrors\.ubuntu\.com\/mirrors\.txt/' /etc/apt/sources.list

1
请详细解释一下。其他想使用您的解决方案的人都希望阅读清晰明了的答案。 - Hamed Baziyad
快速提示:当在 sed 字符串中有斜杠时,可以选择不同的分隔符来避免 "leaning toothpick syndrome",例如 sed -i -e 's#http://...#...#,这样命令会更易读(易写)。 - Bogd

6

lsb-release包没有包含在最小化的Ubuntu镜像中,但您可以使用/etc/lsb-release/etc/os-release文件代替(第二个常用,可参考此答案进行比较)。

对于Dockerfile,只需将$(lsb_release -cs)更改为$(. /etc/os-release && echo $VERSION_CODENAME),这样您就不需要浪费时间来更新和安装软件包了。


好的建议!但是当我在Docker构建中尝试时,它会提示source: not found。但可以通过使用.. /etc/os-release && echo $VERSION_CODENAME来进行修复。 - Mine
更新后,Dockerfile中的RUN默认使用/bin/sh而不是/bin/bash。在bash中,source一个别名,它对应于.,这两者在bash和bourne shell中都可用。 - abuccts

0
在 Dockerfile 中使用 .. /etc/os-release && echo $VERSION_CODENAME 来反映 lsb-release

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接