如何在 Alpine 中安装特定的软件包版本?

Gol*_*den 145 package-management docker alpine-linux

我需要Dockerfile构建一个基于 Alpine Linux 的 Docker 镜像。现在我需要安装一个包作为这个的一部分Dockerfile

目前我有:

RUN apk update && \
    apk upgrade && \
    apk add git
Run Code Online (Sandbox Code Playgroud)

显然这是一个坏主意,因为结果是不确定的。相反,它取决于我构建映像的时间点,以及git正在安装的版本。

这样做的正确方法是什么?

我想我必须告诉updatedupgrade以及add使用哪些版本,但我该怎么做?

我已经看到apk支持固定存储库,但这不是我想要的(至少我是这么认为的),因为我不想固定存储库,而是一个包。

换句话说:如果git可以通过安装npm,我将能够运行:

npm install git@1.9.2
Run Code Online (Sandbox Code Playgroud)

(或我想要的任何版本)。对于 Alpine Linux,这相当于什么?

kai*_*ser 137

您可以像这样设置“粘性”版本:

# Both are equal
apk add packagename=1.2.3-suffix
apk add 'packagename<1.2.3-suffix'
Run Code Online (Sandbox Code Playgroud)

这只会将软件包升级到指定的版本。然后您可以安全地使用……

apk upgrade
Run Code Online (Sandbox Code Playgroud)

升级所有软件包,而带有版本的软件包将保留其版本。要设置最低版本,只需使用...

apk add "packagename>1.2.3-suffix"
Run Code Online (Sandbox Code Playgroud)

如果您找不到包,而您可以在 Alpine 包的 UI 中看到它,请更新您的源/包数据库:

apk update
Run Code Online (Sandbox Code Playgroud)

可以在此处找到包存储库:

https://pkgs.alpinelinux.org/packages
Run Code Online (Sandbox Code Playgroud)

永远不要从 alpine 包回购的“边缘”分支固定包,因为这些正在测试中并且可能会被撤销。(在pkgs.alpinelinux.org/packages,单击“edge”并将其更改为您使用的 alpine 映像版本,然后再次单击“search”。)


牛牛的附加信息

将包固定到一个确切的版本会带来包将从repo 中删除的风险,并且您Dockerfile将来将无法构建。该负责人建议,可以在这里阅读,下面引用。

或者,您可以简单地设置最小包版本而不是精确版本。

我们目前没有资源将所有构建的包无限期地存储在我们的基础设施中。因此,我们目前只为每个稳定分支保留最新的,并且一直如此。

已经讨论了在未来将所有包标记为 Alpine。然而,这仍在“进行中”。官方建议是保留您自己的镜像/存储库,其中包含您可能想要使用的所有特定包及其版本。

— Timo Teräs,@fabled(阿尔卑斯山)


可以在这个自托管的GitLab实例上找到完整的 Alpine Linux 组织存储库。

  • @TravisR 查看 Alpine APK 文档 [此处](https://wiki.alpinelinux.org/wiki/Alpine_Linux_package_management#Advanced_APK_Usage)。 (2认同)
  • Semver 波浪号范围也像在 `apk add ansible~=2.4.1` 中一样工作,意思是 `&gt;=2.4.1 &lt;2.5.0`。查看 http://jubianchi.github.io/semver-check 以测试您自己的范围。 (2认同)
  • @WillVousden 你[在这里阅读此评论](https://medium.com/@devalias/i-dont- believe-they-delete-the-old-versions-so-much-as-the-newer-version- of-alpine-eg-63d18daae710)?它们不会删除包,但您需要仔细制作您的*Docker 映像*。 (2认同)

小智 23

目前,无法从 Alpine Linux 的官方存储库中安装任意旧版本的软件包。您可以实现的最好的事情是使用早期版本的存储库:

# cat /etc/alpine-release
3.3.3

# echo 'http://dl-cdn.alpinelinux.org/alpine/v3.2/main' >> /etc/apk/repositories

# apk update
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/community/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.2/main/x86_64/APKINDEX.tar.gz

# apk add bash==4.3.33-r0
(1/1) Updating pinning bash (4.3.33-r0)
OK: 13 MiB in 17 packages

# apk add bash==4.3.42-r3
(1/2) Upgrading bash (4.3.33-r0 -> 4.3.42-r3)
Executing bash-4.3.42-r3.post-upgrade
(2/2) Purging ncurses5-libs (5.9-r1)
Executing busybox-1.24.1-r7.trigger
OK: 13 MiB in 16 packages
Run Code Online (Sandbox Code Playgroud)

  • 此示例展示了如何在使用 v3.3 Alpine Linux 时从 Alpine 软件包存储库的 v3.2 分支拉取。请注意,混合分支/版本不受官方支持。 (3认同)

cow*_*tor 7

使用 apk 固定 alpine 包的语法是apk add packageName=x.y.z.

要设置最低版本,请使用 apk add packageName>x.y.z

例子:

FROM alpine:3.3
RUN apk update && apk upgrade
RUN apk add --no-cache \
  git=2.8.6-r0 \
  bash=4.3.42-r6 \
  python3=3.5.1-r0
Run Code Online (Sandbox Code Playgroud)

然而,官方的 Alpine 包仓库可以从任何分支中删除任何包版本。这意味着如果您将包固定到 Dockerfile 中的确切版本,您的 Dockerfile 将来可能无法使用。

固定确切包版本的官方建议是保留您自己的镜像/存储库,其中包含您可能想要使用的所有特定包及其版本。

或者,您可以使用最小包版本而不是精确的固定包版本。


小智 7

弗拉德·弗罗洛夫已经给出了答案。我正在编写 docker 解决方案。我试图从 v3.8 存储库添加一些包。

  • 浏览旧存档http://dl-cdn.alpinelinux.org/alpine/并获取软件的特定存储库版本。
  • 获取存储库版本后,将该版本添加到您的 docker 文件中
  • 从存储库中指定包的确切版本

    RUN echo 'http://dl-cdn.alpinelinux.org/alpine/v3.8/main' >> /etc/apk/repositories
    RUN apk update
    RUN apk --no-cache add ca-certificates=20190108-r0 gettext=0.19.8.1-r2 postfix=3.3.0-r4 rsyslog=8.34.0-r1 libsasl=2.1.26-r15
    
    Run Code Online (Sandbox Code Playgroud)