Flatpak

出自 ArchWiki

来自项目 README: “Flatpak 是一个用于构建、分发和运行沙盒化桌面应用程序的 Linux 系统。”

来自 flatpak(1)

Flatpak 是一个用于管理应用程序及其所用运行时的工具。在 Flatpak 模型中,应用程序可以独立于它们所使用的宿主系统构建和分发,并且在运行时它们在一定程度上与宿主系统隔离(“沙盒化”)。
Flatpak 使用 OSTree 来分发和部署数据。它使用的仓库是 OSTree 仓库,可以使用 ostree 实用程序进行操作。已安装的运行时和应用程序是 OSTree 检出。
警告
  • flathub 上提供的许多 Flatpak 应用程序默认情况下并没有被有效沙盒化 [1]。在未首先审查相关 flatpak 权限清单以了解常见的沙盒逃逸问题之前,请勿依赖所提供的进程隔离。
  • 运行不受信任的代码永远是不安全的;沙盒化无法改变这一点。

安装

安装 flatpak 软件包。如果您想构建 flatpak,也请安装 flatpak-builder

桌面集成

为了让 flatpak 应用程序与您的桌面交互(即允许应用程序打开 URL、共享屏幕等),请确保设置 xdg-desktop-portal。根据您的桌面的实现,在应用程序能够访问某些门户之前,会有一个确认对话框。

应用管理

  • Discover — KDE Flatpak 前端,可帮助您查找和安装应用程序、游戏和工具。属于 plasma 的一部分。
https://apps.kde.org/discover/ || discover
  • GNOME Software — GNOME Flatpak 前端,可让您安装和更新应用程序和系统扩展。属于 gnome 的一部分。
https://apps.gnome.org/Software/ || gnome-software

权限管理

  • Flatpak 权限管理 KCM — KDE 配置模块,允许更改已授予已安装的 Flatpak 应用程序的权限。属于 plasma 的一部分。
https://invent.kde.org/plasma/flatpak-kcm || flatpak-kcm
  • Flatseal — 用于查看和修改 Flatpak 应用程序权限的图形化实用程序。
https://github.com/tchx84/Flatseal || flatsealAUR
  • malcontent (家长控制) — 实现对非管理员帐户可访问的内容类型进行限制的支持。属于 gnome 的一部分。
https://gitlab.freedesktop.org/pwithnall/malcontent || malcontent

管理仓库

注意: 默认情况下,每个 flatpak 命令都是系统范围的,即软件包是为计算机的所有用户安装的;同样默认情况下,flatpak 要求用户提供 root 密码。要为单个用户安装软件包和使用仓库(无需超级用户权限),您可以向每个命令添加 --user 选项。例如,如果您只想添加对您可见的仓库,则应执行 flatpak remote-add --user name location

添加仓库

要添加远程 flatpak 仓库,请执行

$ flatpak remote-add name location

其中 name 是新远程仓库的名称,location 是仓库的路径或 URL。

flatpak 的安装将在默认情况下添加官方 Flathub 仓库作为系统范围的安装。要添加官方仓库并进行每用户配置

$ flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo

删除仓库

要删除远程 flatpak 仓库,请执行

$ flatpak remote-delete name

其中 name 是要删除的远程仓库的名称。

列出仓库

要列出所有已添加的仓库,请执行

$ flatpak remotes

管理运行时和应用

注意: 如果已使用 每用户 配置添加了远程仓库,则可以将 --user 选项附加到以下 flatpak 命令。例如,要安装仅对您可见的软件包,请运行 flatpak install --user package-name

搜索远程运行时或应用

在能够在新添加的远程仓库中搜索运行时或应用程序之前,我们需要检索它的 appstream 数据

$ flatpak update
Looking for updates...
Updating appstream data for remote name

然后我们可以继续使用 flatpak search packagename 搜索软件包,例如 查找配置了 flathub 远程仓库的 libreoffice 软件包

$ flatpak search libreoffice
Application ID              Version Branch Remotes Description                       
org.libreoffice.LibreOffice         stable flathub The LibreOffice productivity suite

列出所有可用的运行时和应用

要列出名为 remote 的远程仓库中所有可用的运行时和应用程序,请执行

$ flatpak remote-ls remote

安装运行时或应用

要安装运行时或应用程序,请执行

$ flatpak install remote name

其中 remote 是远程仓库的名称,name 是要安装的应用程序或运行时的名称。

提示: 您可以使用部分标识符 flatpak install partial-name(例如 flatpak install libreoffice)。

列出已安装的运行时和应用

要列出已安装的运行时和应用程序,请执行

$ flatpak list

运行应用

二进制文件位于 /var/lib/flatpak/exports/bin 中,该目录由 /etc/profile.d/flatpak-bindir.sh 自动添加到 $PATH。您可能需要重新登录以应用更改。

也可以使用命令行运行 Flatpak 应用程序

$ flatpak run name

更新运行时或应用

列出有可用更新的运行时和应用程序

$ flatpak remote-ls --updates

要更新名为 name 的运行时或应用程序,请执行

$ flatpak update name

要更新所有应用程序和运行时

$ flatpak update

通过 systemd 自动更新

警告: 通常不建议通过 systemd 运行无人值守的更新,因为应用程序可能会在用户不知情的情况下获得新的权限。有关示例,请参阅 此博客文章

要自动更新系统运行时和应用程序,请创建以下文件

/etc/systemd/system/flatpak-update.service
[Unit]
Description=Update Flatpak
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/flatpak update --noninteractive --assumeyes

[Install]
WantedBy=multi-user.target
/etc/systemd/system/flatpak-update.timer
[Unit]
Description=Update Flatpak

[Timer]
OnBootSec=2m
OnActiveSec=2m
OnUnitInactiveSec=24h
OnUnitActiveSec=24h
AccuracySec=1h
RandomizedDelaySec=10m

[Install]
WantedBy=timers.target

之后,执行 daemon-reload启用/启动 flatpak-update.timer 单元

注意
  • 本指南适用于系统 flatpak 安装,这是 flatpak 中的默认设置。对于用户 flatpak 安装
    • /etc/systemd/user/ 目录中创建上述文件。
    • flatpak-update.service 中的 ExecStart 行中添加 --user 标志。
    • 使用 --user 标志运行 systemctl 命令。

卸载运行时或应用

要卸载名为 name 的运行时或应用程序,请执行

$ flatpak uninstall name

要在卸载时从 ~/.var/app 和权限存储中删除应用程序数据,请使用

$ flatpak uninstall --delete-data name
提示: 您可以使用 flatpak uninstall --unused 卸载未使用的 flatpak “refs”(也称为没有应用程序/运行时的孤立项)。

降级运行时或应用

要降级运行时或应用程序,首先查找关联的提交 ID

$ flatpak remote-info --log remote name

其中 remote 是仓库(例如 flathub),name 是应用程序或运行时的名称。然后,部署提交

$ flatpak update --commit=commit name

其中 commit 是所需版本的提交,name 与之前相同。

此过程也可用于选择性地将软件包升级到不是最新版本的所需版本。

要从 flatpak update 中排除更新此软件包,请参阅 #阻止运行时或应用更新

阻止运行时或应用更新

要阻止对运行时或应用程序进行自动和手动更新,请使用 flatpak mask 命令

$ flatpak mask name

这也阻止了选择性升级和降级。

要反转屏蔽并重新启用更新,请使用 flatpak mask --remove

$ flatpak mask --remove name

将 Flatpak .desktop 文件添加到菜单

Flatpak 期望窗口管理器尊重 XDG_DATA_DIRS 环境变量 变量 以发现应用程序。此变量由脚本 /etc/profile.d/flatpak.sh 设置。更新环境可能需要重启会话。如果启动器不支持 XDG_DATA_DIRS,您可以编辑扫描目录列表并将这些目录添加到其中

~/.local/share/flatpak/exports/share/applications
/var/lib/flatpak/exports/share/applications

已知在 Awesome 中这是必要的。

查看应用的沙盒权限

Flatpak 应用程序带有预定义的沙盒规则,这些规则定义了应用程序允许访问的资源和文件系统路径。要查看特定的应用程序权限,请执行

$ flatpak info --show-permissions name

沙盒权限名称的参考可以在 官方 flatpak 文档中找到。

覆盖应用的沙盒权限

如果您发现应用程序的预定义权限过于宽松或过于严格,您可以使用 flatpak override 命令更改为您想要的任何权限。例如

$ flatpak override --nofilesystem=home name

这将阻止应用程序访问您的主文件夹。

每种类型的权限,例如设备、文件系统或套接字,都有一个命令行选项,该选项允许该特定权限,以及一个单独的选项来拒绝权限。例如,在设备访问的情况下,--device=device_name 允许访问,--nodevice=device_name 拒绝访问设备的权限。

有关所有权限类型命令,请查阅手册页: flatpak-override(1)

可以使用以下命令将权限覆盖重置为默认值

$ flatpak override --reset name

Flatseal 是一个 GUI 权限管理器,提供简单的点击式权限操作。在 KDE Plasma 中,Flatpak 权限管理 KCM 为系统设置应用程序提供了一个类似的 GUI:系统设置 > 应用程序 > Flatpak 权限设置

创建自定义基础运行时

本文或章节需要扩充。

原因: 这当然可以改进。它在 GNOME 应用程序的 D-Bus 方面也存在问题。(在 Talk:Flatpak 中讨论)
警告: 如果您想将您的软件作为 Flatpak 发布到公众,则基于 Arch 的运行时是不合适的。在这种情况下,您需要遵循 官方文档,以使用 通用运行时 将您的软件集成到适当的 Flatpak 生态系统中。
注意
  • 您可能希望使用不受信任的、非特权用户帐户来捆绑不受信任的软件,因为软件在应用程序和运行时创建期间未进行沙盒化。
  • 当向他人分发捆绑包时,您可能在法律上有义务应要求提供某些捆绑软件的源代码。您可能需要使用 ABS 从源代码构建这些软件包。

您可以使用 pacman 为 Flatpak 创建自定义的基于 Arch 的基础运行时和基础 SDK。然后,您可以将其用于构建和打包应用程序。这是个人使用中替代默认 org.freedesktop.BasePlatformorg.freedesktop.BaseSdk 运行时的替代方案。

除了 flatpak 之外,您还需要安装 fakeroot,并且为了支持 pacman hooks,还需要安装 fakechroot

首先,从创建一个目录开始,用于构建运行时和可能的应用程序。

$ mkdir myflatpakbuilddir
$ cd myflatpakbuilddir

然后,您可以准备一个目录来构建运行时基础平台。files 子目录将包含稍后将成为沙盒中的 /usr 目录的内容。因此,您需要创建符号链接,以便仍然可以从通常的路径访问 Arch 中的默认 /usr/share 等。

$ mkdir -p myruntime/files/var/lib/pacman
$ touch myruntime/files/.ref
$ ln -s /usr/usr/share myruntime/files/share
$ ln -s /usr/usr/include myruntime/files/include
$ ln -s /usr/usr/local myruntime/files/local

使您的宿主操作系统字体可用于 Arch 运行时

$ mkdir -p myruntime/files/usr/share/fonts
$ ln -s /run/host/fonts myruntime/files/usr/share/fonts/flatpakhostfonts

在将软件包安装到运行时之前,您需要并且可能想要调整您的 pacman.conf。将 /etc/pacman.conf 复制到您的构建目录,然后进行以下更改

  • 删除 CheckSpace 选项,以便 pacman 不会抱怨在查找根文件系统以检查磁盘空间时出错。
  • 删除任何不需要的自定义仓库以及仅主机系统需要的 IgnorePkgIgnoreGroupNoUpgradeNoExtract 设置。

现在安装运行时的软件包。

$ fakechroot fakeroot pacman -Syu --root myruntime/files --dbpath myruntime/files/var/lib/pacman --config pacman.conf base
$ mv pacman.conf myruntime/files/etc/pacman.conf

通过编辑 myruntime/files/etc/locale.gen 来设置运行时使用的 locale。然后重新生成运行时的 locale。

$ fakechroot chroot myruntime/files locale-gen

基础 SDK 可以从基础运行时创建,其中添加了构建软件包和运行 pacman 所需的应用程序。

$ cp -r myruntime mysdk
$ fakechroot fakeroot pacman -S --root mysdk/files --dbpath mysdk/files/var/lib/pacman --config mysdk/files/etc/pacman.conf base-devel fakeroot fakechroot --needed

插入有关运行时和 SDK 的元数据。

myruntime/metadata
[Runtime]
name=org.mydomain.BasePlatform
runtime=org.mydomain.BasePlatform/x86_64/2016-06-26
sdk=org.mydomain.BaseSdk/x86_64/2016-06-26
mysdk/metadata
[Runtime]
name=org.mydomain.BaseSdk
runtime=org.mydomain.BasePlatform/x86_64/2016-06-26
sdk=org.mydomain.BaseSdk/x86_64/2016-06-26

将基础运行时和 SDK 添加到当前目录中的本地仓库。您可能想要为它们提供适当的提交消息,例如“我的 Arch 基础运行时”和“我的 Arch 基础 SDK”。

$ ostree init --mode archive-z2 --repo=.
$ EDITOR="nano -w" ostree commit -b runtime/org.mydomain.BasePlatform/x86_64/2016-06-26 --tree=dir=myruntime
$ EDITOR="nano -w" ostree commit -b runtime/org.mydomain.BaseSdk/x86_64/2016-06-26 --tree=dir=mysdk
$ ostree summary -u

安装运行时和 SDK。

$ flatpak remote-add --user --no-gpg-verify myarchos file://$(pwd)
$ flatpak install --user myarchos org.mydomain.BasePlatform 2016-06-26
$ flatpak install --user myarchos org.mydomain.BaseSdk 2016-06-26

使用 pacman 创建应用

作为 常用方法 构建应用程序的替代方法,我们可以使用 pacman 创建常规 Arch 软件包的容器化版本。请注意,在创建应用程序时 /usr 是只读的,因此我们在构建应用程序时无法使用 Arch 的软件包。要使用 pacman 创建真正的应用程序,我们可以

  • 使用 pacman 创建包含所有依赖项的运行时
  • 像往常一样 编译应用程序,或者可能使用 pacman 和自定义的 PKGBUILD,该 PKGBUILD 针对 Flatpak 定制,它对 configure 脚本使用 --prefix=/app

或者我们可以

  • 使用 pacman 创建一个运行时,其中包含使用 pacman 安装的应用程序
  • 并创建一个虚拟应用程序来启动它。

为了执行后者,首先使用 pacman 创建一个运行时,例如用于 gedit 的运行时。首先初始化运行时并准备好与 pacman 一起使用。

$ flatpak build-init -w geditruntime org.mydomain.geditruntime org.mydomain.BaseSdk org.mydomain.BasePlatform 2016-06-26
$ flatpak build geditruntime sed -i "s/^#Server/Server/g" /etc/pacman.d/mirrorlist
$ flatpak build geditruntime ln -s /usr/var/lib /var/lib
$ flatpak build geditruntime fakeroot pacman-key --init
$ flatpak build geditruntime fakeroot pacman-key --populate

然后安装软件包。主机的网络连接必须可供 pacman 使用。

$ flatpak build --share=network geditruntime fakechroot fakeroot pacman --root /usr -S gedit

您可以在完成运行时之前(在没有适当的沙盒化的情况下)测试安装。

$ flatpak build --socket=x11 geditruntime gedit

现在完成构建运行时并将其导出到新的本地仓库。pacman 的 GnuPG 密钥具有可能会干扰的权限,需要先删除。

$ flatpak build geditruntime rm -r /etc/pacman.d/gnupg
$ flatpak build-finish geditruntime
$ sed -i "s/\[Application\]/\[Runtime\]/;s/runtime=org.mydomain.BasePlatform/runtime=org.mydomain.geditruntime/" geditruntime/metadata
$ flatpak build-export -r geditrepo geditruntime

然后创建一个虚拟应用程序。

$ flatpak build-init geditapp org.gnome.gedit org.mydomain.BaseSdk org.mydomain.geditruntime

现在完成虚拟应用程序。您可以通过在完成构建时提供其他选项来微调应用程序在沙盒化时的访问权限。有关可能的选项,请参阅 Flatpak 文档GNOME manifest 文件。或者,在完成构建之后但在导出之前,根据您的需要调整 geditapp/metadata。当元数据文件完成时,将应用程序导出到仓库。

$ flatpak build-finish geditapp --socket=x11 [possibly other options] --command=gedit
$ flatpak build-export geditrepo geditapp

将其与运行时一起安装。

$ flatpak --user remote-add --no-gpg-verify geditrepo geditrepo
$ flatpak install --user geditrepo org.mydomain.geditruntime
$ flatpak install --user geditrepo org.gnome.gedit
$ flatpak run org.gnome.gedit

故障排除

Flatpak 无法在 linux-hardened 内核上运行

linux-hardened 内核将 kernel.unprivileged_userns_clone 设置为 0,因此只有特权用户才能创建新的用户命名空间。

修复此问题的一种方法是 安装 bubblewrap-suid。此软件包提供了一个启用 setuid 位的 bwrap(1) 版本,允许 bubblewrap 提升自身权限并创建新的命名空间。

或者,使用 sysctl(8)kernel.unprivileged_userns_clone 设置为 1,从而允许非特权用户创建新的用户命名空间

# sysctl kernel.unprivileged_userns_clone=1
警告: 使用此内核参数值具有负面的安全影响。有关更多信息,请参阅 Security#沙盒化应用程序

要使此更改在重启后仍然存在,请将配置文件添加到 sysctl.d(5)

/etc/sysctl.d/flatpak.conf
kernel.unprivileged_userns_clone=1

有关更多信息,请参阅 Bubblewrap#安装 中的说明。

无法连接到 Wayland 显示器

如果您发现应用程序无法正确打开,并且在 flatpak run 上收到诸如 Failed to connect to Wayland display: No such file or directory 之类的消息:这可能是因为某些其他设置(例如 ELECTRON_OZONE_PLATFORM_HINT="auto")使 Flatpak 应用程序选择 Wayland,而访问 Wayland 未在此应用程序中列入白名单。

可以通过使用 Flatseal 将访问 socket=wayland 列入白名单来解决此问题。

xdg-desktop-portal 启动失败

如果您使用 手动配置的运行命令 启动 X,请确保您包含了参考 `xinitrc` 的所有基本组件。其中一个组件会源自一个脚本,该脚本运行用于 D-Bus 会话服务的环境更新。

systemctl --user import-environment DISPLAY XAUTHORITY
if command -v dbus-update-activation-environment >/dev/null 2>&1; then
   dbus-update-activation-environment DISPLAY XAUTHORITY
fi

Flatpak 应用未采用默认系统主题

如 flatpak 文档 [2] [3] 中所述,没有理想的方法在 flatpak 应用中应用系统主题。最简单的解决方案是使用 Flathub 中可用的主题。但是,有一种解决方法 可用于将主题应用于您的 flatpak 应用程序。stylepak-gitAUR 自动化了这种解决方法。

在 Firefox 中打开本地 HTML 页面时出现“找不到文件”错误

默认情况下,Flatpak 版本的 Firefox 在打开本地 HTML 时将显示“找不到文件”错误页面。这是因为必须授予权限给应用程序才能访问包含该文件的文件夹。

但是,请注意,当授予访问整个主文件夹的权限时,Firefox 将检查 ~/.mozilla 中是否已存在配置文件,并加载它,而不是之前在沙盒文件夹 ~/.var/app/org.mozilla.firefox/cache/mozilla/ 中使用的配置文件。如果在更改权限后(例如使用 Flatseal)丢失了以前会话的选项卡和浏览历史记录,请修改权限以排除对 ~/.mozilla 的访问,或者考虑将配置文件从 ~/.var/app/org.mozilla.firefox/cache/mozilla/ 复制到 ~/.mozilla

链接在基于 wlroots 的合成器上无法打开

尝试打开 URI 的 Flatpak 应用程序使用 xdg-desktop-portal 公开的 org.freedesktop.portal.OpenURI.OpenURI D-Bus 接口。xdg-desktop-portal-wlr 后端 不支持此调用,因此您需要一个额外的后端来填补空白,例如 xdg-desktop-portal-gtk

应用未使用正确的鼠标指针主题

没有单一的标准来正确设置鼠标指针。某些程序只需要读取光标目录的权限,而另一些程序还依赖于其他机制。对于 GTK 应用程序,请确保已安装 xdg-desktop-portal-gtk

否则,以下覆盖应适用于大多数常见的桌面应用程序。

$ flatpak -u override --filesystem=/usr/share/icons/:ro
$ flatpak -u override --filesystem=/home/$USER/.icons/:ro 
$ flatpak -u override --filesystem=xdg-config/gtk-3.0:ro
$ flatpak -u override --env=XCURSOR_PATH=~/.icons

在某些情况下,您可能还需要覆盖环境变量 XCURSOR_THEMEXCURSOR_SIZE

$ flatpak -u override --env=XCURSOR_THEME=Adwaita
$ flatpak -u override --env=XCURSOR_SIZE=24

有关其他详细信息,请参阅 此讨论

显然,不再可能允许应用程序访问 /usr/ 下的目录。启动程序时,以下提示说明了这一点

$ flatpak run com.spotify.Client
F: Not sharing "/usr/share/icons" with sandbox: Path "/usr" is reserved by Flatpak

一种可能的解决方法是将您的图标主题从 /usr/share/icons 手动复制到 /home/$USER/.icons/

Flatpak Qt 应用未使用 Gnome Adwaita 黑暗主题

如果您将主题切换到 Adwaita-dark,但 Flatpak Qt 应用程序仍然使用浅色版本,请安装所需的 KStyle

# flatpak install flathub org.kde.KStyle.Adwaita

运行 Flatpak 应用时出现“权限被拒绝”错误

如果挂载点(其中包含存储应用程序的文件夹,系统范围安装通常为 /var/lib/flatpak/,用户特定安装通常为 ~/.local/share/flatpak/)是以 noexec 选项挂载的,则 Flatpak 应用程序将无法运行。

使用 noexec 设置,您将收到如下错误

$ bwrap: execvp ldconfig: Permission denied
$ error: ldconfig failed, exit status 256

参见