L'application
Podman
Faire tourner ces fichiers compose et ces conteneurs sous Podman plutôt que sous Docker : la distinction podman compose contre podman-compose, et les remarques sur le mode sans privilèges root
Cette page est traduite automatiquement à partir de la documentation en anglais.
Chaque commande docker compose et docker run de cette documentation fonctionne aussi avec Podman. Remplace docker par podman. Cette page documente une fois pour toutes le piège de nommage et les différences en mode rootless. Les autres documents renvoient directement ici au lieu de les répéter.
podman compose n'est pas podman-compose
Ce sont deux outils différents. Choisir le mauvais exécute une implémentation moins compatible sans avertissement.
podman compose(avec une espace) est une sous-commande intégrée à Podman. C'est une fine couche d'encapsulation. Elle trouve un fournisseur compose externe sur ta machine, soitdocker-composesoitpodman-compose, et lui passe la commande. Sidocker-composeest installé, Podman l'utilise en priorité. C'est l'implémentation d'origine de la spécification Compose. Exécutepodman compose versionpour voir le fournisseur affiché dans une bannière.podman-compose(avec un tiret) est une implémentation distincte de la spécification Compose, écrite en Python. Elle fonctionne seule, sans Docker. Elle prend en charge une part plus réduite de la spécification. Sa prise en charge dedepends_on: condition: service_healthyest plus faible, et elle nomme les réseaux différemment par défaut.
Sans aucun fournisseur, podman compose ne fait rien. Une installation propre d'Ubuntu 24.04 avec seulement podman répond à chaque commande podman compose par Error: looking up compose provider failed. Installe d'abord un fournisseur :
sudo apt install podman podman-compose
podman compose version # names /usr/bin/podman-compose, version 1.0.6Sur cette machine, podman compose et podman-compose exécutent le même programme. Les healthchecks de ces fichiers compose fonctionnent avec lui. compose.yml et compose.core.yml ont renvoyé healthy avec podman 4.9.3 et podman-compose 1.0.6, y compris l'attente de Postgres. Les healthchecks utilisent une seule ligne de shell simple (wget -q -O /dev/null http://127.0.0.1:3000/...) pour cette raison. L'ancienne syntaxe node -e "fetch(...)" parvenait à podman-compose 1.0.6 sous forme de ligne de shell tronquée. podman ps renvoyait alors unhealthy en boucle pendant que l'application répondait.
Chaque fichier compose qui démarre Postgres (compose.core.yml, compose.full.yml, et le quickstart compose.yml de openplate-core) utilise depends_on: condition: service_healthy pour conditionner un service au healthcheck de Postgres. Si tu utilises un autre fournisseur, vérifie qu'il gère cette condition.
Remarques sur le mode sans privilèges root
Podman tourne sans privilèges root par défaut. Les conteneurs tournent avec ton propre utilisateur, pas root. Cela renforce la sécurité. Cela introduit aussi trois différences avec Docker à connaître avant de passer à l'Auto-hébergement.
Labels SELinux sur les volumes. Sur un hôte avec SELinux en mode enforcing, ce qui est le réglage par défaut sur Fedora, un conteneur ne peut pas lire ou écrire dans un dossier hôte monté en bind sans label d'accès conteneur. Ajoute :Z au montage si un seul conteneur l'utilise. Ajoute :z si plusieurs conteneurs le partagent, par exemple -v ./pg-data:/var/lib/postgresql:Z. Aucun des fichiers compose de ces trois dépôts ne monte de dossier hôte en bind. Tous utilisent des volumes nommés, que Podman labellise automatiquement. Cette remarque s'applique uniquement si tu modifies une entrée volumes: pour utiliser un chemin hôte. Ce changement concerne les paliers de synchronisation 2 et 4 pour Postgres, et le palier 3 d'inférence pour les poids du modèle.
Ports inférieurs à 1024. Un conteneur rootless ne peut pas lier un port hôte inférieur à 1024 sans permission, par exemple via sudo sysctl net.ipv4.ip_unprivileged_port_start=80. Aucun des ports par défaut de ces fichiers compose (3000, 3001, 8300) n'en a besoin. Ce problème se produit seulement si tu rediriges un port vers 80 ou 443 pour contourner un reverse proxy. Comme chaque palier publie au moins un port, cela peut toucher l'un quelconque des 4 paliers.
Postgres sans privilèges root. Le conteneur Postgres s'exécute sous un utilisateur non-root. Cet utilisateur doit posséder son dossier de données. Un volume nommé règle cela automatiquement, et apps/core/docker/compose.yml, compose.core.yml ainsi que compose.full.yml l'utilisent déjà. Podman crée le volume nommé avec les bons droits de propriété. Si tu passes à un dossier hôte monté en bind, configure d'abord les droits depuis l'hôte avec podman unshare chown -R 70:70 ./pg-data. L'identifiant utilisateur 70 correspond à l'utilisateur postgres dans l'image figée postgres:18-alpine ; les images Debian utilisent 999. Sans cette étape, le conteneur échoue au démarrage avec une erreur de permissions. Cela concerne les paliers 2 et 4.
Unités Quadlet
Quadlet n'utilise ni podman compose ni podman-compose : systemd lance chaque conteneur avec podman lui-même. Si tu veux seulement Quadlet, saute l'installation du fournisseur ci-dessus.
Chaque fichier compose ci-dessus est aussi fourni sous forme d'unités systemd rootless. Elles sont générées par scripts/quadlet.sh et stockées dans docker/quadlet/. Un ensemble d'unités persiste aux redémarrages sous systemctl --user sans processus compose actif. Chaque dossier comprend un README avec les étapes d'installation, les fichiers env lus par chaque unité, et des journaux d'exécutions de test :
- app : niveau 1, l'application seule
- core : niveau 2, Postgres, l'application et openplate-core
- inference : niveau 3, openplate-inference et l'application
- full : niveau 4, les quatre composants
- openplate-core : le serveur central autonome
- openplate-inference : le point de terminaison d'inférence seul
Choisis une seule voie : compose ou Quadlet, jamais les deux. Une unité systemd personnalisée exécutant podman compose up et un ensemble d'unités Quadlet accomplissent la même tâche. Si tu installes les deux, ils entrent en conflit au démarrage sur le port 3000. Supprime le service existant avant de basculer vers Quadlet. Pour retirer Quadlet, suis les étapes de désinstallation dans le README du scénario.
Deux choses à savoir avant de commencer, sur n'importe quel Podman :
- Il n'y a pas d'étape
systemctl --user enable. Le générateur de Podman crée les services. Tu ne peux pas activer des unités générées. Lancer cette commande renvoieFailed to enable unit: Unit /run/user/1000/systemd/generator/app.service is transient or generated.C'est un comportement normal. Le démarrage automatique s'appuie sur la ligne[Install] WantedBy=default.targetdans chaque unité, avecloginctl enable-linger "$USER". Cette commande démarre ton instance systemd utilisateur au boot plutôt qu'à la première connexion. - Chaque paramètre va dans
<unit>.env, jamais dans l'unité. Chaque unité lit deux fichiers env depuis son propre dossier :<unit>.defaults.env, fourni avec les unités et contenant les valeurs par défaut de compose, puis<unit>.env, qui est le tien. Podman les lit dans cet ordre, donc une ligne dans le tien l'emporte. Ton fichier doit exister, même vide, sinon le conteneur ne démarre pas. Une mise à jour copie à nouveau les unités et les fichiers par défaut, et laisse ton fichier intact. Le README du scénario liste les valeurs que l'on modifie habituellement.
Podman 4.9, la version d'Ubuntu 24.04, diffère de Podman 5 sur deux points :
- Il ignore
Notify=healthy, qui nécessite Podman 5.0 ou plus récent. Par conséquent,systemctl --user startse termine environ une seconde après le lancement du conteneur, avant la fin du healthcheck. Une unité avecRequires=n'attendra pas l'état de santé dépendant. Vérifie manuellement l'état du conteneur :bashuntil [ "$(podman inspect --format '{{.State.Health.Status}}' systemd-app)" = healthy ]; do sleep 5; done
- Il ne lit aucun répertoire de surcharge (
app.container.d/*.conf). Les fichiers placés ici ne produisent aucun effet. Les unités n'en ont pas besoin : chaque valeur modifiable est lue depuis<unit>.env.