Flatpak et Nix
Voir aussi : vidéo youtube - vidéo peertube - journal linuxfr
Flatpak est un “système de construction et de déploiement d’applications de bureau sur Linux”. C’est un outil assez similaire à Snap et à AppImage, les fameux “gestionnaires de paquets universels”. Ces gestionnaires de paquets sont censés apporter deux avantages principaux :
permettre à un utilisateur normal d’installer des logiciels, qui ne sont pas forcément fournis par la logithèque de sa distribution;
permettre à un développeur de packager un logiciel facilement pour tout un ensemble de distributions Linux.
Il existe également une autre approche de la gestion de paquets, proposée par Nix et GNU Guix et basée sur la composition d’environnements logiciels sans effet de bord. Cette approche apporte également les fonctionnalités recherchées par les gestionnaires de paquets universels.
Cet article présente les deux approches (à travers Flatpak et Nix) d’un point de vue pratique, à la fois côté utilisateur (installer un logiciel) et côté développeur (packager un logiciel). Il ne s’agit cependant pas d’une comparaison exhaustive ni fiable.
Avertissement : j’ai essayé d’être le plus objectif possible mais mon propos est biaisé par le fait que je connaisse assez bien Nix alors que mon expérience avec Flatpak est très réduite.
Installer Flatpak et Nix
Avec une distribution Linux “classique”
Flatpak est souvent fourni directement par la logithèque système.
sudo apt install flatpak
Pour installer Nix, il faut généralement utiliser le script fourni par Nix.
curl https://nixos.org/nix/install | sh
echo ". $HOME/.nix-profile/etc/profile.d/nix.sh" >> ~/.bashrc
source ~/.bashrc
Avec NixOS
NixOS est une distribution Linux basée sur Nix mais qui supporte également Flatpak, via un service qu’il suffit d’activer.
- éditer la configuration système (le fichier
/etc/nixos/configuration.nix
) :
true;
services.flatpak.enable =
{
xdg.portal = enable = true;
extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
};
- mettre à jour la configuration système :
sudo nixos-rebuild switch
Installer et utiliser un paquet
Premier cas d’utilisation : un utilisateur normal (non administrateur) veut installer et lancer un logiciel fourni par Flatpak ou par Nix.
Avec Flatpak
La procédure est décrite dans la documentation de Flatpak.
- ajouter un dépôt Flatpak :
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak update
- chercher et exécuter un logiciel :
flatpak search geany
...
flatpak run org.geany.Geany
Avec Nix
La procédure est décrite dans la documentation de Nix.
- ajouter un canal de paquets :
nix-channel --add https://nixos.org/channels/nixos-19.09 nixpkgs
nix-channel --update
- chercher et exécuter un logiciel :
nix search geany
...
nix run nixpkgs.geany -c geany
Comparaison
Flatpak ou Nix, la procédure pour récupérer et lancer un logiciel est très similaire.
Concernant la documentation, celle de Flatpak est meilleure : la procédure est décrite pas-à-pas dans une section dédiée. La documentation de Nix est plus difficile : les informations sont assez dispersées dans les différentes sections du manuel.
Concernant le nombre de paquets, la logithèque de Nix est beaucoup plus fournie que celle de Flatpak. Cependant, Flatpak n’a pas (encore) pour objectif de concurrencer les logithèques classiques mais plutôt de fournir des logiciels qui n’y sont habituellement pas (parce que trop récent, trop confidentiel, non-libre, etc).
Enfin, d’un point de vue technique, les deux outils téléchargent des paquets
binaires et les réutilisent si déjà téléchargés. La logithèque standard de
Nix est centralisée et semble donc plus
propice à la réutilisation des paquets. Flatpak utilise des sources plus
variées (org.gnome
, org.kde
, org.freedesktop
…) ce qui multiplie le
risque de dépendances non-mutualisées.
Créer un paquet
Second cas d’utilisation : un développeur veut packager une application.
Projet d’exemple
Il s’agit d’un helloworld en C++, utilisant la bibliothèque gtkmm
et compilé
via cmake
et pkg-config
.
hello.cpp
:
#include <gtkmm.h>
int main(int argc, char ** argv) {
::Main kit(argc, argv);
Gtk::Window window;
Gtk::Label label(" Hello ! ");
Gtk.add(label);
window.set_default_size(200, 100);
window.show_all();
window.run(window);
kitreturn 0;
}
CMakeLists.txt
:
cmake_minimum_required( VERSION 3.0 )
project( hello )
find_package( PkgConfig REQUIRED )
pkg_check_modules( PKG_GTKMM REQUIRED gtkmm-3.0 )
include_directories( ${PKG_GTKMM_INCLUDE_DIRS} )
add_executable( hello hello.cpp )
target_link_libraries( hello ${PKG_GTKMM_LIBRARIES} )
install( TARGETS hello DESTINATION bin )
Créer un paquet avec Flatpak
La procédure est documentée ici et le code source du projet est disponible ici.
installer
flatpak-builder
installer un runtime/SDK Flatpak :
flatpak install flathub org.gnome.Platform//3.32 org.gnome.Sdk//3.32
- écrire un fichier de packaging (
org.flatpak.hello.json
) :
{
"app-id": "org.flatpak.hello",
"runtime": "org.gnome.Platform",
"runtime-version": "3.32",
"sdk": "org.gnome.Sdk",
"command": "hello",
"finish-args": [
"--socket=x11"
],
"modules": [
{
"name": "mm-common",
"cleanup": [ "/" ],
"sources": [
{
"type": "archive",
"url": "https://download.gnome.org/sources/mm-common/0.9/mm-common-0.9.12.tar.xz",
"sha256": "ceffdcce1e5b52742884c233ec604bf6fded12eea9da077ce7a62c02c87e7c0b"
}
]
},
...
{
"name": "hello",
"buildsystem": "cmake",
"builddir": true,
"sources": [
{
"type": "dir",
"path": "."
}
]
}
]
}
- construire et tester le paquet :
flatpak-builder build-dir org.flatpak.hello.json
flatpak-builder --run build-dir org.flatpak.hello.json hello
Créer un paquet avec Nix
- écrire un fichier de packaging (
default.nix
) :
with import <nixpkgs> {};
{
stdenv.mkDerivation name = "hellonix";
src = ./.;
buildInputs = [
cmake
gtkmm3
pkgconfig];
}
- compiler et tester :
nix-build
./result/bin/hello
Comparaison
Dans les grandes lignes, la construction d’un paquet suit toujours à peu près les mêmes étapes : récupérer un environnement logiciel, écrire un fichier de packaging, réaliser le packaging en utilisant le fichier et l’environnement précédents.
Avec Nix, le packaging ne pose ici pas de problème particulier. Comme la logithèque standard est bien fournie, il suffit d’indiquer l’outils de compilation et les dépendances. Nix permet, si besoin, d’ajouter ou de modifier des dépendances, ou de personnaliser les différentes étapes du packaging. Les principales difficultés avec Nix sont la documentation peu pédagogique et son langage très particulier.
Le packaging avec Flatpak est plus compliqué. La documentation est pédagogique
mais l’exemple présenté est trop simple (pas de dépendance ni d’étape de
compilation). De plus, il faut spécifier un runtime Flatpak (et sa version)
mais la
documentation
n’est pas très détaillée à ce sujet. Enfin, la gestion des dépendances est
assez pénible : apparemment, il faut les spécifier soi-même sous forme de
modules dans le fichier de packaging. Pour simplifier le travail, on peut
utiliser un logiciel comme gnome-builder
mais le fichier résultant est
complexe et semble difficile à maintenir efficacement.
D’un point de vue plus technique, on peut regarder comment les ressources et
les produits sont isolés et réutilisés. Avec Nix, tout est stocké dans le
/nix/store
(dépendances, paquets construits…). Les paquets sont donc
réutilisés au niveau du système complet : si un paquet est utilisé par
différents utilisateurs ou par différents projets, ce sont les fichiers du
/nix/store
qui sont effectivement utilisés. De plus, le /nix/store
est en
lecture seule et ne peut être manipulé que via les outils Nix, ce qui assure
l’isolation. Avec Flatpak, il semble effectivement y avoir réutilisation et
isolation pour les paquets installés par l’utilisateur ainsi que pour les
runtimes utilisés par le développeur. En revanche, la construction d’un paquet
crée un dossier .flatpak-builder
, notamment pour gérer les modules de
dépendances. Ce dossier est créé pour chaque projet, donc sans réutilisation.
De plus, il s’agit d’un simple dossier caché sans restriction de droit
particulière, donc relativement peu isolé.
Conclusion
D’un point de vue factuel
Cet article a comparé un gestionnaire de paquets “universels” (Flatpak) avec un gestionnaire de paquets “composables sans effet de bord” (Nix). Les deux objectifs principaux étaient (1) de permettre à un utilisateur normal d’installer un logiciel sans avoir à passer par la logithèque système ni à compiler manuellement, (2) de permettre à un développeur de packager et de distribuer un logiciel sans avoir à construire différents types de paquets pour les différents types de distributions.
Globalement, Flatpak et Nix atteignent ces objectifs. Flatpak est bien intégré dans une bonne partie des distributions Linux, possède une documentation très (trop ?) pédagogique et propose un hub de paquets communautaires. Nix est beaucoup moins présent dans les logithèques des distributions Linux et doit généralement être installé manuellement. Sa documentation est bien fournie mais assez difficile d’accès. Nix propose plusieurs solutions pour distribuer des paquets : logithèque officielle, logithèque communautaire, service de cache…
Sur l’exemple traité ici, le packaging semble plus facile avec Nix. De plus, de par sa conception (composition de paquets sans effet de bord), Nix semble implémenter plus efficacement l’isolation et la réutilisation des paquets, notamment pour le développeur. À travers son écosystème (NixOS, Nixpkgs, Nixops…), Nix propose également beaucoup d’autres fonctionnalités : gérer les services systèmes, construire des images Docker, gérer des environnements logiciels multi-langages, définir et déployer des micro-services ou des systèmes complets, etc. De son côté, Flatpak prévoit d’implémenter un système de sandboxing de services utilisateurs (accès au système de fichiers, à la caméra, etc) qui n’a pas d’équivalent dans Nix.
D’un point de vue personnel
Tout d’abord, je rappelle que mon opinion sur le sujet est forcément biaisée car j’utilise, promeus et contribue à l’écosystème Nix depuis plusieurs années. Avec Nix, je connais à peu près les outils, les pièges à éviter et comment fouiller dans la doc, ce qui n’est pas le cas avec Flatpak. Cependant, j’ai vraiment essayé d’aborder Flatpak objectivement, avec même l’espoir de l’utiliser pour certains de mes projets.
Par rapport à une logithèque Linux classique, Flatpak (et les gestionnaires de paquets universels en général) permet à un utilisateur normal d’installer des logiciels et à un développeur de packager un peu plus efficacement pour Linux. Ce sont effectivement des avantages significatifs qui peuvent valoriser Linux sur le secteur du desktop. D’un point de vue purement technique, il me semble qu’on aurait également pu implémenter un mode “utilisateur” dans, par exemple, APT et ainsi continuer à utiliser la chaine APT + DEB + PPA. Mais d’un point de vue humain, je peux comprendre qu’il faille repartir sur un système “indépendant”, même si Flatpak semble quand même pas mal poussé par IBM Fedora. Oups, un troll s’est glissé dans la phrase précédente, sauras-tu le trouver ?
Enfin, par rapport à Nix, Flatpak a l’avantage d’apporter une doc plus pédagogique, un site web plus joli, et… c’est tout. Non seulement, Nix permet également à un utilisateur d’installer des logiciels et à un développeur de packager un logiciel mais en plus Nix repose sur des concepts éprouvés, a une logithèque énorme et apporte plein d’autres fonctionnalités (cf la section précédente). Alors ok, c’est mon opinion personnelle biaisée et tout, mais je ne vois rien dans Flatpak qui n’existe pas déjà dans Nix ou qui ne pourrait pas y être implémenté sans trop de problème. Et comble de la cerise sur le gateau qui fait déborder le vase, Nix est apparu environ 10 ans avant Flatpak; ça aurait peut-être été bien que les différentes communautés collaborent un peu plus ensemble… Bref, pour finir sur une note positive : Flatpak c’est bien, mais si vous avez l’occasion de tester Nix (voire NixOS), foncez.