Концепции и архитектура Flatpak#

Flatpak — это система сборки, распространения и запуска настольных приложений в изолированной среде (песочнице) на Linux. В отличие от классических пакетных менеджеров, Flatpak отделяет приложение от конкретного дистрибутива: одна и та же сборка может работать на разных версиях ОС без перекомпиляции.

Технология основана на нескольких ключевых принципах:

  • Изоляция — каждое приложение работает в песочнице, ограниченной пространствами имён ядра Linux (namespaces) и фильтрами системных вызовов (seccomp).

  • Декларативность — все разрешения и зависимости приложения описываются в метаданных (манифесте). Пользователь или администратор может переопределить разрешения после установки, но исходный набор всегда явно задекларирован.

  • Воспроизводимость — рантайм предоставляет фиксированный набор библиотек, благодаря чему приложение ведёт себя одинаково на любой системе.

  • Атомарность обновлений — обновления применяются целиком или не применяются вовсе, что исключает состояние частично обновлённого приложения.

Терминология#

Ниже определены ключевые термины, используемые в документации и в командах Flatpak.

Рантайм (Runtime)#

Рантайм — это базовый набор разделяемых библиотек и ресурсов, на которые опираются приложения. Рантайм содержит системные библиотеки (libc, libssl, zlib и т. д.), фреймворки (Qt, GTK) и вспомогательные утилиты. Рантайм монтируется в песочницу приложения по пути /usr и доступен только для чтения.

Одна версия рантайма может использоваться множеством приложений одновременно. Обновление рантайма автоматически обновляет библиотечную базу всех зависящих от него приложений.

Рантаймы именуются в формате обратного DNS: например, org.example.Platform. Каждая версия рантайма хранится в отдельной ветке (branch), обычно совпадающей с номером мажорной версии.

SDK#

SDK (Software Development Kit) — расширенная версия рантайма, дополненная заголовочными файлами, компиляторами, инструментами сборки и отладки. SDK используется исключительно на этапе сборки приложения и не устанавливается на целевую систему.

Связь между рантаймом и SDK определяется на уровне метаданных: при инициализации сборки разработчик указывает оба идентификатора — рантайм для запуска и SDK для компиляции.

Приложение (Application)#

Приложение — конечный продукт, который устанавливается и запускается пользователем. Файлы приложения монтируются в песочнице по пути /app. Приложение не имеет прямого доступа к хостовой файловой системе, устройствам или сетевым ресурсам за пределами явно предоставленных разрешений.

Каждое приложение идентифицируется строкой в формате обратного DNS: org.example.MyApp. Идентификатор должен содержать минимум две точки и состоять из латинских букв, цифр, точек и дефисов.

Ссылка (Ref)#

Ссылка — полный адрес объекта в репозитории Flatpak. Формат ссылки:

<тип>/<идентификатор>/<архитектура>/<ветка>

Примеры:

app/org.example.MyApp/x86_64/stable
runtime/org.example.Platform/x86_64/23.08

Тип принимает значения app (приложение) или runtime (рантайм/SDK). Архитектура указывается в формате, принятом в Flatpak: x86_64, aarch64, arm, i386.

Ветка (Branch)#

Ветка определяет версионную линию рантайма или приложения. Для рантаймов ветка, как правило, совпадает с мажорной версией (23.08, 24.08), для приложений часто используется значение stable.

Flatpak поддерживает параллельную установку нескольких веток одного и того же рантайма, что позволяет приложениям, собранным под разные версии рантайма, работать одновременно.

Песочница (Sandbox)#

Песочница — среда исполнения, ограничивающая доступ приложения к ресурсам хостовой системы. Реализация основана на следующих механизмах ядра Linux:

  • Пространства имён (namespaces) — изолируют файловую систему (mount), сеть (network), идентификаторы процессов (PID), пользователей (user) и межпроцессное взаимодействие (IPC).

  • Seccomp — ограничивает набор системных вызовов, доступных процессу.

  • Bubblewrap (bwrap) — низкоуровневая утилита, создающая песочницу с необходимым набором пространств имён и монтирований.

Приложение внутри песочницы видит файловую систему, составленную из:

  • /usr — файлы рантайма (только чтение);

  • /app — файлы приложения (только чтение);

  • /var — изменяемые данные;

  • ~/.var/app/<id> — данные приложения на хосте.

Порталы (Portals)#

Порталы — механизм безопасного взаимодействия приложения в песочнице с хостовой системой через D-Bus. Вместо прямого доступа к файлам или устройствам приложение отправляет запрос на портал, а пользователь принимает решение через стандартный диалог.

Примеры порталов:

  • FileChooser — выбор файлов через системный диалог (приложение получает доступ только к выбранному файлу);

  • OpenURI — открытие ссылок внешним обработчиком;

  • Print — печать документов;

  • Screenshot — захват экрана;

  • Notification — отправка уведомлений.

OSTree#

OSTree — хранилище, лежащее в основе репозиториев Flatpak. Принцип работы аналогичен Git, но применяется к бинарным файлам операционной системы:

  • Каждая версия приложения или рантайма фиксируется как коммит — неизменяемый снимок файлового дерева.

  • Коммиты образуют историю, что позволяет откатиться к предыдущей версии.

  • Файлы хранятся с дедупликацией по контрольным суммам, что экономит дисковое пространство.

  • Статические дельты — предварительно рассчитанные разности между версиями, ускоряющие загрузку обновлений.

Репозиторий Flatpak представляет собой OSTree-репозиторий с дополнительными метаданными (summary, AppStream-индексы, GPG-подписи).

Расширения (Extensions)#

Расширения — механизм подключения дополнительных компонентов к рантайму или приложению. Расширение монтируется в определённый каталог внутри песочницы.

Типичные применения расширений:

  • Локализации (языковые пакеты);

  • Кодеки и медиабиблиотеки;

  • Темы оформления;

  • Дополнительные модули (плагины) приложения.

Точка расширения определяется в метаданных рантайма или приложения и включает имя, каталог монтирования и условия загрузки.

Разрешения (Permissions / finish-args)#

Разрешения определяют, к каким ресурсам хостовой системы имеет доступ приложение. Они фиксируются при сборке в секции finish-args манифеста и записываются в метаданные Flatpak-пакета.

Категории разрешений:

Сокеты (sockets)

Управляют доступом к графическим подсистемам, звуку и шинам:

Значение

Описание

x11

Доступ к X11-серверу

wayland

Доступ к Wayland-композитору

fallback-x11

X11 только при отсутствии Wayland

pulseaudio

Доступ к звуковой подсистеме PulseAudio

cups

Доступ к подсистеме печати CUPS

pcsc

Доступ к устройствам смарт-карт (PC/SC)

ssh-auth

Доступ к агенту SSH-аутентификации

session-bus

Полный доступ к сессионной шине D-Bus

system-bus

Полный доступ к системной шине D-Bus

Устройства (devices)

Значение

Описание

dri

Доступ к GPU (аппаратное ускорение графики)

kvm

Доступ к /dev/kvm (виртуализация)

shm

Доступ к /dev/shm (разделяемая память)

all

Доступ ко всем устройствам /dev

Разделяемые ресурсы (shares)

Значение

Описание

network

Доступ к сети

ipc

Межпроцессное взаимодействие (IPC namespace, необходимо для X11)

Файловые системы (filesystems)

Управляют доступом к каталогам хостовой файловой системы:

Значение

Описание

home

Домашний каталог пользователя

host

Вся файловая система хоста

host-os

Каталог /usr хоста (только чтение)

host-etc

Каталог /etc хоста (только чтение)

xdg-desktop

Рабочий стол (~/Desktop)

xdg-documents

Документы (~/Documents)

xdg-download

Загрузки (~/Downloads)

xdg-music

Музыка (~/Music)

xdg-pictures

Изображения (~/Pictures)

xdg-videos

Видео (~/Videos)

/абсолютный/путь

Произвольный каталог (абсолютный путь)

К любому значению можно добавить суффикс :ro (только чтение), :rw (чтение и запись) или :create (создать при отсутствии).

Персистентные каталоги (persist)

Каталоги, перечисленные в persist, создаются в ~/.var/app/<id>/ и монтируются в домашний каталог приложения. Это позволяет приложению сохранять конфигурацию между запусками без доступа к реальному домашнему каталогу.

D-Bus (own-name / talk-name)

Определяют, какие имена на шине D-Bus приложение может занимать (own-name) и к каким сервисам обращаться (talk-name). Аналогичные параметры system-own-name и system-talk-name действуют для системной шины.

Переменные окружения (env / unset-env)

Позволяют задать или удалить переменные окружения внутри песочницы.

Сравнение с deb-пакетами#

Flatpak и deb — два принципиально разных подхода к распространению ПО. Ниже приведено детальное сравнение по ключевым аспектам.

Модель зависимостей#

deb: Зависимости разрешаются пакетным менеджером (APT/dpkg) из общего пула пакетов дистрибутива. Каждая библиотека устанавливается один раз в /usr/lib и используется всеми пакетами. Конфликт версий между пакетами приводит к неразрешимым зависимостям.

Flatpak: Зависимости делятся на два уровня. Системные библиотеки предоставляются рантаймом (одна копия на все приложения, использующие данный рантайм). Специфичные библиотеки, отсутствующие в рантайме, включаются непосредственно в пакет приложения. Разные приложения могут использовать разные версии одной библиотеки без конфликтов.

Изоляция#

deb: Пакет устанавливается глобально в системные каталоги. Приложение имеет полный доступ к файловой системе, устройствам и сети с правами запустившего пользователя.

Flatpak: Каждое приложение работает в песочнице. Доступ к ресурсам определяется декларативным набором разрешений, зафиксированным при сборке. По умолчанию приложение не имеет доступа ни к чему за пределами своей песочницы.

Обновления#

deb: Обновление заменяет файлы пакета на диске. Процесс не атомарен — при сбое система может оказаться в состоянии с частично обновлёнными файлами. Откат к предыдущей версии возможен только при наличии старого .deb-файла или через механизмы snapshot.

Flatpak: Обновление создаёт новый коммит в OSTree-репозитории и переключает символическую ссылку атомарно. При сбое старая версия остаётся полностью работоспособной. Откат к предыдущей версии выполняется одной командой.

Кроссдистрибутивность#

deb: Пакет собирается под конкретную версию дистрибутива. Установка на другую версию или другой дистрибутив, как правило, невозможна из-за различий в версиях базовых библиотек.

Flatpak: Пакет опирается на рантайм, а не на конкретный дистрибутив. Один и тот же Flatpak-пакет работает на любой системе, где установлен совместимый рантайм и сам Flatpak.

Интеграция с системой#

deb: Полная интеграция — пакет может устанавливать systemd-юниты, cron-задания, правила udev, модули ядра, конфигурационные файлы в /etc, скрипты в /usr/bin.

Flatpak: Ограниченная интеграция — приложение может экспортировать .desktop-файлы, иконки, данные AppStream, сервисы D-Bus. Системные сервисы, модули ядра и глобальная конфигурация недоступны.

Архитектура файловой системы#

Приложение внутри Flatpak-песочницы видит файловую систему, отличную от хостовой. Рассмотрим, как она устроена.

Структура каталогов в песочнице#

/
├── app/                  # Файлы приложения (только чтение)
│   ├── bin/              # Исполняемые файлы
│   ├── lib/              # Библиотеки приложения
│   ├── share/            # Данные (иконки, desktop-файлы, переводы)
│   └── ...
├── usr/                  # Файлы рантайма (только чтение)
│   ├── bin/              # Системные утилиты
│   ├── lib/              # Системные библиотеки
│   ├── share/            # Данные рантайма
│   └── ...
├── etc/                  # Конфигурация (из рантайма, только чтение)
├── var/                  # Изменяемые данные
│   ├── tmp/
│   └── ...
└── run/                  # Временные данные сессии

Каталоги /app и /usr доступны только для чтения во время исполнения. Изменяемые данные приложения хранятся на хосте в ~/.var/app/<идентификатор>/.

Структура сборочного каталога#

На этапе сборки (до экспорта в репозиторий) приложение представлено каталогом со следующей структурой:

build-dir/
├── metadata              # INI-файл с метаданными (ID, рантайм, разрешения)
├── files/                # Файлы приложения (станут /app в песочнице)
│   ├── bin/
│   ├── lib/
│   └── share/
├── export/               # Файлы, экспортируемые на хост
│   └── share/
│       ├── applications/ # .desktop-файлы
│       ├── icons/        # Иконки
│       └── metainfo/     # AppStream-метаданные
└── var/                  # Начальное содержимое /var

Каталог export/ содержит файлы, которые становятся видимы хостовой системе после установки (иконки в трее, записи в меню приложений, данные для центра приложений).

Метаданные (metadata)#

Файл metadata в сборочном каталоге имеет формат INI и определяет ключевые характеристики пакета:

[Application]
name=org.example.MyApp
runtime=org.example.Platform/x86_64/stable
sdk=org.example.Sdk/x86_64/stable
command=myapp

[Context]
shared=network;ipc;
sockets=x11;wayland;pulseaudio;
devices=dri;
filesystems=xdg-download;

[Session Bus Policy]
org.freedesktop.Notifications=talk

Для рантаймов используется секция [Runtime] вместо [Application].

Репозитории Flatpak#

Репозиторий Flatpak — это OSTree-репозиторий, содержащий коммиты приложений и рантаймов. Репозиторий может быть локальным (каталог на диске) или удалённым (доступным по HTTP/HTTPS/FTP).

Структура репозитория#

repo/
├── config                # Конфигурация OSTree-репозитория
├── summary               # Индекс всех доступных ссылок
├── summary.sig           # GPG-подпись индекса
├── refs/                 # Ссылки на текущие коммиты
│   └── heads/
│       ├── app/
│       │   └── org.example.MyApp/x86_64/stable
│       └── runtime/
│           └── org.example.Platform/x86_64/stable
├── objects/              # Объекты (файлы, каталоги, коммиты)
│   ├── 00/
│   ├── 01/
│   └── ...
├── deltas/               # Статические дельты для обновлений
└── appstream/            # Метаданные AppStream

Файл summary содержит список всех доступных ссылок с контрольными суммами и используется клиентом для определения доступных обновлений. Его необходимо пересоздавать при каждом изменении репозитория (командой flatpak build-update-repo или flatpak-builder --repo).

Подключение удалённого репозитория#

Для подключения удалённого репозитория на клиентской машине выполняется:

flatpak remote-add --if-not-exists <имя> <url-репозитория>

Если репозиторий подписан GPG-ключом, ключ импортируется при добавлении:

flatpak remote-add --gpg-import=<путь-к-ключу.gpg> <имя> <url-репозитория>

Репозиторий также можно подключить через файл .flatpakrepo — текстовый файл в формате INI, содержащий URL репозитория, его название, GPG-ключ и другие параметры. Такие файлы обычно размещаются на сайте репозитория и позволяют подключить его в один клик или одной командой:

flatpak remote-add --if-not-exists <имя> <путь-к-файлу.flatpakrepo>

Пример содержимого .flatpakrepo:

[Flatpak Repo]
Title=Название репозитория
Url=https://example.org/repo
Homepage=https://example.org
Comment=Описание репозитория
GPGKey=<base64-кодированный GPG-ключ>

Установка и обновление приложений#

Установка:

flatpak install <имя-репозитория> <идентификатор-приложения>

Обновление всех установленных пакетов:

flatpak update

Откат к предыдущей версии:

flatpak update --commit=<хеш-коммита> <идентификатор-приложения>

Жизненный цикл Flatpak-пакета#

Процесс создания и распространения Flatpak-пакета состоит из следующих этапов:

Рисунок 1
Рисунок 1
  1. Сборка — приложение компилируется из исходного кода (через flatpak-builder или команды flatpak build-*) либо формируется из существующих deb-пакетов (через aft-app).

  2. Экспорт — собранное приложение экспортируется в локальный OSTree-репозиторий командой flatpak build-export или автоматически при использовании flatpak-builder --repo.

  3. Тестирование — приложение устанавливается из локального репозитория и проверяется на корректность работы.

  4. Публикация — локальный репозиторий размещается на HTTP-сервере или приложение упаковывается в однофайловый бандл (flatpak build-bundle).

  5. Установка — пользователь подключает репозиторий и устанавливает приложение стандартными средствами Flatpak.