fpm (Effing Package Management) construit des paquets .deb, .rpm et .apk à partir des mêmes fichiers, sans devenir expert du format natif de chaque distribution. Ce guide montre comment installer fpm, empaqueter un binaire ou un script en paquet Debian, RHEL et Alpine, et y ajouter métadonnées, dépendances et scripts d'installation. Pour administrateurs et développeurs débutants à intermédiaires. Toutes les sorties proviennent d'un lab réel (fpm 1.17.0). En fin de guide, le comparatif avec nfpm pour choisir le bon outil.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Installer fpm et les outils natifs requis
- Construire un
.deb, un.rpmet un.apkdepuis les mêmes sources - Ajouter métadonnées, dépendances et scripts d'installation
- Choisir entre fpm et nfpm
Prérequis
Section intitulée « Prérequis »- Un binaire, un script ou un répertoire à empaqueter
- Ruby (fpm est écrit en Ruby) et les outils natifs de la cible (
dpkgpour le.deb,rpmpour le.rpm)
Pourquoi fpm
Section intitulée « Pourquoi fpm »Chaque distribution a son format de paquet et ses outils : dpkg-deb et les fichiers debian/ côté Debian, rpmbuild et les fichiers .spec côté RHEL. Apprendre chacun est long. fpm part d'une source (-s) et produit une cible (-t), en masquant cette complexité :
- Sources (
-s) : un répertoire (dir), une archivetar, un gem Ruby, un module Python, un paquet npm, ou même un.deb/.rpmexistant à reconvertir. - Cibles (
-t) :deb,rpm,apk(Alpine),pacman,tar, et d'autres.
Le même jeu de fichiers donne donc un paquet pour toutes les distributions visées, en changeant un seul argument.
Installer fpm
Section intitulée « Installer fpm »fpm s'installe en gem Ruby, après les paquets système. Installez aussi l'outil natif de chaque format que vous voulez produire.
sudo apt updatesudo apt install -y ruby ruby-dev build-essential# outils natifs des cibles voulues :sudo apt install -y dpkg # pour produire des .debsudo apt install -y rpm # pour produire des .rpmsudo gem install fpmsudo dnf install -y ruby ruby-devel gcc make rpm-buildsudo gem install fpmVérifiez l'installation :
fpm --version1.17.0Construire un .deb depuis un répertoire
Section intitulée « Construire un .deb depuis un répertoire »Préparez l'arborescence à empaqueter, puis lancez fpm. Ici un script installé dans /usr/local/bin :
mkdir -p src/usr/local/binprintf '#!/bin/sh\necho bonjour\n' > src/usr/local/bin/monoutilchmod 0755 src/usr/local/bin/monoutil
fpm -s dir -t deb -n monoutil -v 1.0.0 \ --description "Outil de demo" --maintainer "Stephane" \ -C src usr/local/bin/monoutil{:timestamp=>"...", :message=>"Created package", :path=>"monoutil_1.0.0_amd64.deb"}L'option -C src (chdir) entre dans src avant de lire les fichiers, pour que l'arborescence du paquet démarre à usr/local/bin. Vérifiez le résultat avec les outils Debian :
dpkg -I monoutil_1.0.0_amd64.deb # métadonnées Package: monoutil Version: 1.0.0 Architecture: amd64 Maintainer: Stephane Description: Outil de demodpkg -c monoutil_1.0.0_amd64.deb # contenu-rwxr-xr-x 0/0 23 ./usr/local/bin/monoutil-rw-r--r-- 0/0 125 ./usr/share/doc/monoutil/changelog.gzLe paquet est installable avec sudo apt install ./monoutil_1.0.0_amd64.deb.
Le même paquet en .rpm et .apk
Section intitulée « Le même paquet en .rpm et .apk »Pour produire les autres formats, seule la cible -t change. Le même mapping de fichiers donne un .rpm :
fpm -s dir -t rpm -n monoutil -v 1.2.0 --iteration 1 \ --description "Outil demo" --maintainer "Stephane" --license MIT \ --depends bash \ src/usr/local/bin/monoutil=/usr/local/bin/monoutilIci on utilise la syntaxe source=destination : le fichier local est placé à /usr/local/bin/monoutil dans le paquet. Vérifiez avec les outils RPM :
rpm -qip monoutil-1.2.0-1.x86_64.rpmName : monoutilVersion : 1.2.0Release : 1License : MITSummary : Outil demoEt le format Alpine se génère de la même façon avec -t apk :
fpm -s dir -t apk -n monoutil -v 1.0 \ src/usr/local/bin/monoutil=/usr/local/bin/monoutilCreated package {:path=>"monoutil_1.0_noarch.apk"}Métadonnées, dépendances et scripts
Section intitulée « Métadonnées, dépendances et scripts »Les métadonnées se passent en options, identiques quelle que soit la cible :
| Option | Rôle |
|---|---|
-n, -v | nom et version du paquet |
--iteration | numéro de build (la release RPM, la debian_revision) |
-a | architecture (amd64, noarch...) |
--depends | une dépendance (répétable) |
--description, -m, --url, --license | description, mainteneur, URL, licence |
fpm sait aussi attacher des scripts de cycle de vie déclenchés à l'installation ou la suppression : --before-install, --after-install, --before-remove, --after-remove.
printf '#!/bin/sh\necho post-install lance\n' > after.shfpm -s dir -t rpm -n monoutil -v 1.2.0 --after-install after.sh \ src/usr/local/bin/monoutil=/usr/local/bin/monoutilLe script est bien embarqué, vérifiable côté RPM :
rpm -qp --scripts monoutil-1.2.0-1.x86_64.rpmpostinstall scriptlet (using /bin/sh):#!/bin/shecho post-install lancefpm ou nfpm : lequel choisir
Section intitulée « fpm ou nfpm : lequel choisir »nfpm (de l'équipe GoReleaser) est l'alternative moderne. Le choix dépend de votre contexte.
| Critère | fpm | nfpm |
|---|---|---|
| Langage / dépendance | Ruby (gem) | binaire Go autonome, zéro dépendance |
| Configuration | impérative (CLI) | déclarative (nfpm.yaml versionné) |
| Sources d'entrée | dir, gem, python, npm, deb, rpm... | fichiers uniquement (contents) |
| Cibles | deb, rpm, apk, pacman, tar... | deb, rpm, apk, ipk, archlinux |
| Signature des paquets | non native (outil externe) | native (deb, rpm, apk) |
| Intégration CI/CD | à scripter | intégrée à GoReleaser |
En clair : nfpm brille dans un pipeline CI/CD reproductible (config YAML, binaire unique, signature native), surtout pour distribuer un binaire Go. fpm reste imbattable quand l'entrée n'est pas un simple répertoire : convertir un gem, un module Python ou repackager un .rpm en .deb, ce que nfpm ne fait pas.
Pièges à connaître
Section intitulée « Pièges à connaître »- Dépendance Ruby : fpm impose Ruby et
ruby-dev, là où nfpm est un binaire autonome. En CI, prévoyez l'installation du gem. - Pas de signature native : fpm ne signe pas les
.deb. Signez après coup (dpkg-sigpour deb,rpm --addsignou--rpm-signpour rpm). - Fichiers de
/etc: les outils Debian marquent souvent tout ce qui est sous/etccomme fichier de configuration, ce qui change le comportement aux mises à jour. Vérifiez vos chemins. - Pas de résolution de dépendances :
--dependspose les métadonnées, mais c'est à vous de déclarer le bon graphe ; fpm ne le calcule pas.
À retenir
Section intitulée « À retenir »- fpm construit
.deb,.rpmet.apkdepuis les mêmes sources : seul-tchange. - Il s'installe en gem Ruby et exige l'outil natif de chaque cible (
dpkg,rpm). -s dir+ mappingsource=destinationest le mode le plus courant ;-Cchange le répertoire de base.- Métadonnées (
-n,-v,--depends,--license) et scripts (--after-install...) sont communs à toutes les cibles. - fpm ne signe pas les paquets : signez après création pour une distribution publique.
- Pour un pipeline Go reproductible, regardez nfpm ; pour convertir gem/python/npm, restez sur fpm.