Alpine 包管理器
本页面介绍了 Alpine 包管理器 (APK)。如需快速入门,请参阅 使用 APK。在 无盘 模式下的软件包管理需要涉及 Alpine 本地备份工具 (lbu) 的额外步骤。
概述
apk-tools 提供了 apk,它支持以下操作:
add | 添加新软件包或升级运行系统上的软件包 |
del | 从运行系统删除软件包 |
fix | 修复软件包或系统 |
update | 更新可用软件包的索引 |
info | 打印关于已安装或可用软件包的信息 |
search | 使用通配符模式搜索软件包或描述 |
upgrade | 升级当前已安装的软件包 |
cache | 本地缓存软件包仓库的维护操作 |
version | 比较已安装和可用软件包之间的版本差异 |
index | 从软件包列表创建仓库索引 |
fetch | 下载(但不安装)软件包 |
audit | 列出从初始软件包安装状态到文件系统的更改 |
verify | 验证软件包签名 |
dot | 为给定软件包创建 graphviz 图形描述 |
policy | 显示更新给定软件包的仓库,以及也提供该软件包的仓库 |
stats | 显示统计信息,包括已安装和可用软件包的数量、目录和文件数量等。 |
manifest | 显示给定软件包中包含文件的校验和 |
软件包和仓库
Alpine Linux 的软件包是经过数字签名的 tar.gz 压缩包,其中包含程序、配置文件和依赖元数据。它们的扩展名为 .apk
,通常称为 “a-packs”。Alpine Linux 中的软件包被组织到三个官方 仓库中。从技术上讲,任何包含 *.apk 文件集合以及名为 APKINDEX.tar.gz 的特殊索引文件的目录都可以被视为仓库,尽管它可能是个人仓库。Pinned Repositories 可以用于 阻止特定版本的软件包。
子包
在 Alpine Linux 中,二进制软件包被精简并拆分为子包,以便更好地控制安装的功能,并尽可能保持安装的小巧和高效。
World
在 /etc/apk/world 中,apk 维护着 world,即软件包选择需要满足的约束列表。World 描述了期望的系统状态。命令 apk add foo
和 apk del bar
通过在 /etc/apk/world 中添加 foo 或 bar 作为依赖约束来操作期望的状态。
/etc/apk/world 是一个纯文本文件,每行使用依赖表示法表示一个约束。每行的格式为:name{@tag}{[<>~=]version}
为了使系统被认为是正确的,此处列出的每个约束都必须是可解决的,并且不得提交任何不正确的事务。如果它无法验证所请求更改的正确性,它将在尝试更改系统上实际安装的软件包之前撤回添加约束。因此,apk 永远不会 提交导致系统无法启动的更改。
如果手动编辑了 /etc/apk/world,请运行 apk fix
以将已安装的软件包与期望的系统状态同步。软件包的安装或删除是修改此系统状态的副作用。
apk fix
更新软件包列表
随着软件包的添加和升级,Alpine Linux 仓库会发生变化。要获取最新的可用软件包列表,请使用 update 命令。该命令从每个仓库下载 APKINDEX.tar.gz,并将其存储在本地缓存中,通常是 /var/cache/apk/、/var/lib/apk/ 或 /etc/apk/cache/。
apk update
将 --update-cache
或简写 -U
开关添加到另一个 apk 命令(如 apk --update-cache upgrade
或 apk -U add ...
)中,该命令的效果与在其他 apk 命令之前首先运行 apk update
相同。
最好总是在执行 upgrade 或 add 命令之前先执行 update。这样,该命令将从 仓库安装最新的可用软件包。
添加软件包
使用 add 从 仓库安装软件包。任何必要的依赖项也会被安装。如果您有多个仓库,add 命令将安装最新的软件包。
apk add openssh apk add openssh openntp vim
可以通过向软件包添加标签来安装来自 pinned 仓库的软件包。
apk add wireguard-go@testing
.
添加本地软件包
要安装本地可用的 apk 软件包,例如,如果此设备没有互联网访问权限,但您可以直接将 apk 软件包上传到该设备,请使用 --allow-untrusted 标志
apk add --allow-untrusted /path/to/file.apk
请注意,可以指定多个软件包。安装本地软件包时,还应指定所有依赖项。例如
apk add --allow-untrusted /var/tig-2.2-r0.apk /var/git-2.11.1-20.apk
移除软件包
使用 del 删除软件包(以及不再需要的依赖项)。
apk del openssh apk del openssh openntp vim
升级运行中的系统
要获取运行系统中当前安装的 发布分支的最新安全升级和错误修复,需要执行两个步骤
- update 可用软件包列表
- upgrade 已安装的软件包
apk update apk upgrade
或者,将它们合并为一个命令
apk -U upgrade
这是一个示例,展示了在具有 pinned 仓库的系统上执行此过程
# apk update fetch https://dl-3.alpinelinux.org/alpine/v3.6/main/x86_64/APKINDEX.tar.gz fetch https://dl-3.alpinelinux.org/alpine/v3.6/community/x86_64/APKINDEX.tar.gz fetch https://dl-3.alpinelinux.org/alpine/edge/testing/x86_64/APKINDEX.tar.gz v3.6.2-191-gf98d79930f [https://dl-3.alpinelinux.org/alpine/v3.6/main] v3.6.2-190-ga5d68c47df [https://dl-3.alpinelinux.org/alpine/v3.6/community] v3.6.0-4624-g11f1b9c8ab [https://dl-3.alpinelinux.org/alpine/edge/testing] OK: 20118 distinct packages available # apk upgrade (1/2) Upgrading extra-cmake-modules@testing (5.38.0-r0 -> 5.39.0-r0) (2/2) Upgrading extra-cmake-modules-doc@testing (5.38.0-r0 -> 5.39.0-r0) Executing mdocml-apropos-1.14.1-r0.trigger OK: 2635 MiB in 803 packages
要仅升级特定软件包,请使用 upgrade 命令并指定它们
apk update apk upgrade busybox
要启用无人值守的软件包自动升级,请参阅 apk-autoupdate 软件包。请参阅 升级 Alpine 以将 Alpine Linux 升级到较新的 发布分支。
升级 “无盘” 和 “数据” 磁盘模式安装
对于升级 无盘 和 数据磁盘 模式安装,升级运行系统需要 一些额外的步骤。
搜索软件包
search 命令在仓库索引文件中搜索可安装的软件包。
返回格式为 软件包-版本。对于 apk add 软件包,请省略 版本
示例
- 列出所有可用的软件包,以及它们的描述
apk search -v
- 列出所有属于 ACF 系统的软件包
apk search -v 'acf*'
- 要列出所有将 NTP 列为其描述一部分的软件包,请使用 -d 或 --description 选项
apk search -v --description 'NTP'
- 列出所有提供
git
命令的软件包apk search -v 'cmd:git'
软件包信息
info 命令提供有关软件包内容、其依赖项以及哪些文件属于软件包的信息。
对于给定的软件包,可以选择每个元素(例如,-w 仅显示网页信息),或者使用 -a 命令显示所有信息。
示例
apk info -a zlib
zlib-1.2.5-r1 description: A compression/decompression Library zlib-1.2.5-r1 webpage: https://zlib.net zlib-1.2.5-r1 installed size: 94208 zlib-1.2.5-r1 depends on: libc0.9.32 zlib-1.2.5-r1 is required by: libcrypto1.0-1.0.0-r0 apk-tools-2.0.2-r4 openssh-client-5.4_p1-r2 openssh-5.4_p1-r2 libssl1.0-1.0.0-r0 freeswitch-1.0.6-r6 atop-1.25-r0 zlib-1.2.5-r1 contains: lib/libz.so.1.2.5 lib/libz.so.1 lib/libz.so zlib-1.2.5-r1 triggers:
如示例所示,您可以确定
- 软件包的 描述(-d 或 --description)
- 应用程序托管的 网页(-w 或 --webpage)
- 软件包安装后将需要的 大小(以字节为单位)(-s 或 --size)
- 使用此软件包所需的软件包 (依赖项)(-R 或 --depends)
- 需要安装此软件包的软件包 (被依赖项)(-r 或 --rdepends)
- 软件包的 内容,即它安装的文件(-L 或 --contents)
- 此软件包设置的任何 触发器。 (-t 或 --triggers) 此处列出的是被监视的目录;如果目录发生更改,则在 apk add/delete 结束时运行触发器脚本。例如,在安装所有添加内核模块的软件包后执行一次 depmod。
检查文件所有权
info 命令也很有用,可以确定文件属于哪个软件包。例如
apk info --who-owns /sbin/lbu
将显示
/sbin/lbu is owned by alpine-conf-x.x-rx
检查依赖关系
下面解释了 info 命令中用于检查软件包依赖关系和反向依赖关系的特定选项
选项 -R 或 --depends 列出软件包的依赖项。
apk info --depends pipewire
pipewire-1.0.6-r1 depends on: /bin/sh so:libc.musl-x86_64.so.1 so:libpipewire-0.3.so.0
选项 -r 或 --rdepends 列出软件包的反向依赖项(所有其他依赖于该软件包的软件包)。
apk info --rdepends pipewire
pipewire-1.0.6-r1 is required by: xdg-desktop-portal-wlr-0.7.1-r0 pipewire-pulse-1.0.6-r1
列出已安装的软件包
要列出所有已安装的软件包,请使用
apk info
要按字母顺序列出所有已安装的软件包,并提供每个软件包的描述,请执行
apk -vv info
apk 工具没有子命令来列出手动安装的且没有反向依赖项的软件包。要在未使用 lbu 的传统系统上获取此信息,请尝试此脚本。请注意,此方法还将列出不应删除的核心软件包,例如 alpine-base。
#!/bin/sh apk info | grep -ve '-doc$' | sort | while read pkg do rdep=`apk info -qr "$pkg"` [ -z "$rdep" ] && echo $pkg done
apk dot
dot 选项将软件包依赖项呈现为 graphviz 图形。下面记录了使用 dot 选项的步骤
将 apk dot 选项的输出保存到 dot 文件。
$ apk dot seatd > seatd_dependencies.dot
使用 Graphviz 将 dot
文件转换为图形格式,例如 PNG、PDF 或 SVG。
$ dot -Tpng seatd_dependencies.dot -o seatd_dependencies.png

apk policy
要显示软件包的安装来源和更新来源的仓库,以及任何 标记或启用的仓库(如果存在也提供该软件包),对于此架构 - 其 policy
apk policy package
例如
$ apk policy vlc vlc policy: 2.2.6-r1: lib/apk/db/installed https://dl-3.alpinelinux.org/alpine/v3.7/community 3.0.0_rc2-r1: @edgecommunity https://dl-3.alpinelinux.org/alpine/edge/community
本地缓存
APK 可以将已安装软件包的缓存保存在本地磁盘上。HDD 或 sys 模式 安装不需要 apk 缓存,但它仍然允许通过网络提供软件包,例如供其他本地计算机安装。
随着时间的推移,当较新的软件包添加到缓存时,软件包的旧版本默认保留在缓存目录中。可以使用 clean 命令删除软件包的旧版本。
apk cache clean
或者要查看删除了什么,请包含 verbose 开关
apk -v cache clean
如果软件包意外地从缓存目录中删除,请使用 download 命令,
apk cache download
上述两个步骤可以与 sync 命令合并为一个 - 这将清除旧软件包并下载丢失的软件包。
apk cache -v sync
高级 APK 用法
命令行仓库选项
默认情况下,apk 实用程序将使用系统仓库进行所有操作。此行为可以通过以下选项覆盖
--repositories-file REPOFILE | 通过指定仓库文件来覆盖系统仓库。 |
-X|--repository REPO | 指定一个补充仓库,该仓库将与系统仓库一起使用。此选项可以多次提供。 |
apk add cherokee --update-cache --repository https://dl-cdn.alpinelinux.org/alpine/edge/testing/ --allow-untrusted
保持特定软件包版本
在某些情况下,您可能想要升级系统,但将特定软件包保持在较低版本。可以添加 “粘性” 或版本化依赖项。例如,将 asterisk 软件包保持在 1.6.2 或更低版本
apk add asterisk=1.6.0.21-r0
或
apk add 'asterisk<1.6.1'
之后
apk upgrade
将升级整个系统,同时将 asterisk 软件包保持在 1.6.0 或更低版本。
要稍后升级到当前版本,
apk add 'asterisk>1.6.1'
将确保 1.6.1 是使用的最低版本。
您还可以使用 “模糊” 版本匹配将版本固定到主要/次要版本。例如
apk add 'asterisk=~1.6'
将匹配任何以 1.6 开头的 asterisk 版本(例如 1.6.0.21-r0 或 1.6.9.31-r9)。
如果您希望通过软件包固定来实现确定性的、可重复的软件包安装(例如在使用容器化环境时),那么了解您的软件包仓库的版本保留规则非常重要。始终固定到 intended for your release branch 的软件包版本。在 edge 分支上固定到某个版本后,软件包版本从仓库中撤销后可能会停止工作。
Commit 钩子
如果您想在 apk 每次提交时触发操作或运行特定脚本,那么有一种内置方法可以做到这一点。在每次提交时,apk 都会查找位于 “/etc/apk/commit_hooks.d/” 目录中的可执行文件,并在提交之前和之后执行它们。为了提供一种选择性地在 apk 提交更改之前或之后运行钩子的方法,脚本被调用时使用 “pre-commit” 或 “post-commit” 作为参数 1。这是一个在提交之前和之后执行不同操作的钩子示例
#!/bin/sh if [ "$1" = "pre-commit" ]; then do_something elif [ "$1" = "post-commit" ]; then do_something_else fi
Commit 钩子是 $PATH-aware 的,因此为了安全起见,建议指定可执行文件的绝对路径。
Rosetta Stone
Rosetta Stone 或 比较图表 显示了与 Alpine Linux 相比,其他流行的发行版中与软件包管理相关的标准操作是如何完成的。
故障排除
错误:无法选择软件包
此错误通常表示软件包管理器无法找到合适的软件包进行安装。在发出命令添加软件包时,例如:apk add labwc,您可能会收到以下错误消息
ERROR: unable to select packages: labwc (no such package): required by: world[labwc]
上述错误表明 labwc 在 仓库中不存在,该仓库当前在 /etc/apk/repositories 中配置。确保 community
仓库已 启用,因为默认情况下仅启用 main
仓库。您可能还需要查看 软件包数据库 以确定正确的软件包名称以及软件包可用的 仓库。
错误:无法满足的约束
此错误表示存在依赖关系冲突。这意味着您尝试安装的软件包具有无法在当前软件包仓库中同时满足的依赖项。
您可能需要查看 软件包数据库 以确定正确的软件包名称和版本以及软件包可用的 仓库。
警告:此 apk-tools 版本过旧!
apk update、apk upgrade 或 apk add 可能会报告以下内容
WARNING: This apk-tools is OLD! Some packages might not function properly
如果您正在运行 Alpine Linux 稳定版本,并且还安装了某些 edge/main、edge/community 或 testing 软件包,则可能会发生这种情况。一种解决方案是考虑升级 apk-tools。如果 edge 已在您的仓库中 标记,请尝试
apk add --upgrade apk-tools@edge
错误:不信任的签名
当发布版本更改时,会发生这种情况。您需要更新本地 apk 密钥。
如果您已更新仓库,请允许它们在没有受信任密钥的情况下更新
apk update --allow-untrusted
然后安装密钥升级
apk fix --upgrade --allow-untrusted alpine-keys
现在更新和升级应该正常进行。
另一种选择是,可以在仓库更新之前,如前所述,直接获取、验证和安装更新后的 alpine-keys 软件包。
World 已更新,但以下软件包未被移除
在发出命令删除软件包时,例如:apk del btrfs-progs,您可能会收到以下错误消息
World updated, but the following packages are not removed due to: btrfs-progs: btrbk
在这里,删除软件包 btrfs-progs 会影响约束文件 /etc/apk/world 中的另一个软件包 btrbk。因此,软件包 btrfs-progs 将从约束文件中删除,但不会从系统中删除。btrfs-progs 将保留在系统中,直到依赖于 btrfs-progs 的约束(即 btrbk)被删除。
如果发出 apk del btrbk,软件包 btrfs-progs 将自动从系统中删除,因为约束 btrfs-progs 在 /etc/apk/world 中不存在。