跳至內容
出自 Arch Linux 中文维基

引自項目 README:「Flatpak 是一個 Linux 桌面程序的構建、分發和沙箱化運行系統。」

引自 flatpak(1)

Flatpak 是一個用來管理應用和應用所使用的運行時的工具。在 Flatpak 模型中,應用的構建和分發不依賴其主系統,並且它們在運行時一定程度上獨立於主系統('沙箱化')。
Flatpak 使用 OSTree 以分發和部署數據。它使用的倉庫是 OSTree 倉庫並且可以用 ostree 的工具來操作,已安裝的運行時和應用都是 OSTree 檢出。
警告:
  • flathub 上的很多 Flatpak 應用默認並未有效地沙箱化[1]。在未檢查 flatpak 相關權限清單是否有沙箱逃逸問題前,請勿依賴提供的檢查隔離功能。
  • 運行不受信任的軟體永不安全,沙箱化也無法改變這一點。

安裝

安裝 flatpak 軟體包。如果需要構建 flatpak,請一併安裝 flatpak-builder

桌面環境整合

對於與桌面環境交互的 flatpak 應用(例如使用應用打開 URL、共享屏幕等),先確保已配置了 XDG 桌面門戶。取決於桌面環境的實現不同,在應用調用功能前會出現一個確認窗口。

應用管理

  • Discover — Flatpak 的 KDE 前端,可用於搜索和安裝應用、遊戲和工具,是 plasma包組 的一部分。
https://apps.kde.org/discover/ || discover
  • GNOME Software — Flatpak 的 GNOME 前端,可用於安裝和更新應用及系統擴展,是 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 命令都是全局可用的,具體來說,軟體包是安裝給當前機器的所有用戶的,並且要求用戶提供 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

官方倉庫的鏡像站

對於中國大陸用戶,有上海交通大學的 Flathub 緩存可供選擇。

使用方法:

sudo flatpak remote-modify flathub --url=https://mirror.sjtu.edu.cn/flathub

如果出現錯誤可嘗試:

wget https://mirror.sjtu.edu.cn/flathub/flathub.gpg
sudo flatpak remote-modify --gpg-import=flathub.gpg flathub
注意:由於重分發授權問題,NVIDIA 驅動、JetBrains 系列等軟體需要從官方伺服器下載,無法使用鏡像站加速。

刪除一個倉庫

要刪除一個遠程 flatpak 倉庫,執行:

$ flatpak remote-delete name

這其中 name 是要刪除的遠程倉庫的名字。

倉庫列表

要列出所有已添加的倉庫列表,執行:

$ flatpak remotes

管理運行時和應用

注意:如果倉庫是用戶獨立的,可以在 flatpak 命令添加 --user 選項。例如,如果要安裝一個只有你可見的應用,可以執行 flatpak install --user 軟體包名稱

搜索遠程倉庫的運行時和應用

在能搜索新添加的遠程倉庫中的運行時和應用之前,我們需要獲取其軟體應用流的數據:

$ 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 環境:
    • /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 依賴(即無應用/運行時依賴的孤立包)。

降級一個運行時或應用

要降級一個運行時或應用,需要先獲取到對應的提交(commit)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 override 命令進行修改。

例如:

$ flatpak override --nofilesystem=home name

這會禁止應用訪問你的用戶主目錄。

所有可以賦予權限的類型,如設備、文件系統或 socket ,都有對應的命令行選項以允許或禁止確切的權限。例如,可以使用 --device=device_name 允許訪問特定設備,而 --nodevice=device_name 會禁用設備訪問權限。

對於所有可操作的權限類型,詳見:flatpak-override(1)

下面的命令可將所有更改過的權限重設為默認:

$ flatpak override --reset name

如果更偏好圖形界面,可以使用 Flatseal;在 KDE Plasma 上,Flatpak 權限管理 KCM 在系統設置中提供了類似的圖形界面:System Settings > Applications > Flatpak Permission Settings

創建自定義基本運行時

這篇文章的某些內容需要擴充。

原因:有待完善,且對於 GNOME 應用存在 D-Bus 問題。 (在 Talk:Flatpak 中討論)
警告:如果要將你的應用作為 Flatpak 發布,不要使用基於 Arch 的運行時。請參考官方文檔使用通用運行時將你的軟體正確地整合到 Flatpak 生態中。
注意:
  • 鑑於在創建應用和運行時期間軟體並沒有沙箱化,你可能會想使用一個單獨的非受信、非特權用戶對不信任的軟體進行打包。
  • 在分發軟體包時,你可能會有法律義務提供一些包內軟體的源碼。你可能會想使用 ABS 從源碼構建軟體包。

除了使用默認的 org.freedesktop.BasePlatformorg.freedesktop.BaseSdk 運行時外,你還可以在自用的情況下,通過 pacman 為 Flatpak 創建一個基於 Arch 的自定義運行時和基本 SDK,然後用其構建並打包軟體。

flatpak 外,你還需要安裝 fakeroot,對於 pacman 鉤子支持還需安裝 fakechroot

首先創建一個目錄,用於構建運行時或應用:

$ mkdir myflatpakbuilddir
$ cd myflatpakbuilddir

然後就可以準備一個用於構建運行時基本平台的目錄,其中的文件將被打包到沙箱中的 /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,配置需要使用的 locales,然後生成 locale:

$ fakechroot chroot myruntime/files locale-gen

可以通過為基礎運行時添加構建軟體包和運行 pacman 所需的應用來創建基礎 SDK:

$ 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 添加到位於當前目錄的本地倉庫,你還可以為倉庫添加例如「My Arch base runtime」和「My Arch base SDK」等提交(commit)信息:

$ 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 創建應用

除了構建應用的通用方式外,我們還可以創建通常 Arch 軟體包的容器化版本。注意,在創建應用時 /usr 是只讀的,因此在構建應用時無法使用 Arch 軟體包。有兩種方式可以通過 pacman 創建軟體:

  • 使用 pacman 創建包含所有依賴的運行時
  • 然後根據正常方式自行構建應用,或是將 pacman 搭配為 Flatpak 定製的 PKGBUILD,其中在 configure 腳本中使用了 --prefix=/app

或是

  • 使用 pacman 創建一個運行時,其中包含通過 pacman 安裝完成的應用
  • 然後使用一個虛擬應用進行啟動

對於後一種方式,以 gedit 為例,首先通過 pacman 創建一個運行時,該運行時已為 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

然後安裝軟體包,這一步需要聯網:

$ 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 files。你還可以在完成構建後和導出前按需修改 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,該包提供了啟用 setuidbwrap(1),使得 bubblewrap 可以自行提升權限並創建新命名空間。

或者,也可以通過 sysctl(8)kernel.unprivileged_userns_clone 設為 1,以允許非特權用戶創建新的用戶命名空間。

# sysctl kernel.unprivileged_userns_clone=1
警告:該操作將給安全性帶來負面影響,具體信息請參考安全#沙盒程序

要將該更改持久化,可以在 sysctl.d(5) 中添加一個配置文件:

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

更多信息請參考 Bubblewrap#安裝

Failed to connect to Wayland display

如果應用未能正常啟動,並在使用 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 無法啟動

If you are starting X with manually-configured run commands, ensure you are including all essential components of the reference `xinitrc`. One of which sources a script which runs an update of the environment used for D-Bus session services.

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 文檔,當前不存在理想的為 flatpak 軟體應用系統主題的方法[2] [3]。最簡單的方式是使用 Flathub 中可用的主題。然而,有辦法可以將主題應用到 flatpak 軟體中,該方法的自動化版本為 stylepak-gitAUR

"File not found" error when Open local HTML pages in Firefox

By default, the Flatpak version of Firefox will display a "File not found" error page when opening a local HTML. This is because permission must be granted to the app for accessing the folder containing the file.

However, note that when granting permission to access the entire Home folder, Firefox will then check for an existing profile in ~/.mozilla and load it instead of those previously in use from the sandboxed folder ~/.var/app/org.mozilla.firefox/cache/mozilla/. If your previous session's tabs and browsing history is missing after changing a permission (e.g. with Flatseal), either modify the permission to exclude access to ~/.mozilla, or consider copying the profile from ~/.var/app/org.mozilla.firefox/cache/mozilla/ to ~/.mozilla.

Links fail to open on wlroots-based compositors

Flatpak applications that attempt to open URIs make use of the org.freedesktop.portal.OpenURI.OpenURI D-Bus interface exposed by xdg-desktop-portal. The xdg-desktop-portal-wlr backend does not support this call and therefore you will need an additional backend to fill the gap, for example xdg-desktop-portal-gtk.

Applications do not use the correct cursor theme

There is no single standard to set the cursor properly. Some programs only need read access to the cursors directory, others also rely on other mechanisms. For GTK applications, ensure that xdg-desktop-portal-gtk is installed.

Otherwise, the following overrides should work for most common desktop applications.

$ 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

In some cases you may also need to override the environment variables XCURSOR_THEME and XCURSOR_SIZE:

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

See this discussion for additional details.

Apparently it is not possible anymore to enable access to applications to directories under /usr/. The following hints at this when launching a program:

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

One possible workaround would be to manually copy your icon theme from /usr/share/icons to /home/$USER/.icons/.

Flatpak Qt applications do not use Gnome Adwaita dark theme

If you switched your theme to Adwaita-dark and Flatpak Qt applications still use the light version, install the required KStyle:

# flatpak install flathub org.kde.KStyle.Adwaita

Permission denied error when running Flatpak applications

Flatpak applications will not run if the mount point that contains the folder in which the application is stored, typically /var/lib/flatpak/ for system wide installations, and ~/.local/share/flatpak/ for user-specific installations, is mounted with the noexec option.

With noexec set you will get errors such as this:

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

參閱