
Quadlet transforme des fichiers déclaratifs en unités systemd pour vos conteneurs Podman. Vous décrivez l'intention (image, ports, volumes), systemd gère le cycle de vie (démarrage, restart, logs).
À la fin de ce cours, vous saurez :
- Démarrer un conteneur comme un service systemd
- Gérer logs, restart et dépendances
- Structurer un mini-stack (volume + réseau + conteneur)
- Choisir entre rootless et rootful
Ce que Quadlet résout
Section intitulée « Ce que Quadlet résout »Avant Quadlet, vous aviez deux options pour exécuter des conteneurs au démarrage :
-
podman generate systemd: génère une unité.serviceavec la commandepodman runcomplète. La commande affiche d'ailleurs son propre avertissement de dépréciation (DEPRECATED command: It is recommended to use Quadlets…). Le défaut de fond se voit dans le fichier produit, qui contient unPIDFiledésignant l'identifiant du conteneur du moment :PIDFile=/run/user/1001/containers/overlay-containers/8cba58e…/userdata/conmon.pidRecréez le conteneur, et cet identifiant change : l'unité générée devient invalide. C'est la raison technique de « figée », et elle explique pourquoi ce chemin ne survit pas à une mise à jour d'image.
-
Écrire un
.serviceà la main : fragile, difficile à maintenir, pas de gestion native des volumes/réseaux.
Quadlet apporte une approche déclarative :
| Approche | Maintenabilité | Fonctionnalités |
|---|---|---|
| Script shell + cron | Fragile | Aucune |
.service manuel | Moyenne | Basiques |
podman generate systemd | Moyenne | Complètes mais figées |
| Quadlet | Excellente | Complètes et évolutives |
Quadlet est maintenant l'approche recommandée par Red Hat pour la production.
Prérequis
Section intitulée « Prérequis »- Linux avec systemd
- Podman 4.4+ (Quadlet intégré depuis cette version)
- Connaissances de base de systemd (
systemctl,journalctl)
Droit au but
Section intitulée « Droit au but »Quatre entrées pour aller directement au bon endroit, selon que vous cherchez un premier essai, la référence des directives, un exemple multi-services ou la résolution d'une panne.
Modèle mental : comment Quadlet fonctionne
Section intitulée « Modèle mental : comment Quadlet fonctionne »Quadlet n'est ni un démon ni un orchestrateur : c'est un générateur que
systemd appelle avant de construire son graphe d'unités. Ce seul point explique
la plupart des surprises, à commencer par le fait qu'un fichier posé sur le
disque reste totalement invisible tant que daemon-reload n'a pas été lancé.
Les trois sous-sections détaillent ce mécanisme, l'emplacement attendu des
fichiers et la façon d'inspecter ce qui a réellement été produit.
Le générateur systemd
Section intitulée « Le générateur systemd »Quadlet est un générateur systemd. Il s'exécute automatiquement :
- Au boot du système
- Après chaque
systemctl daemon-reload
Il lit vos fichiers .container, .volume, .network et génère les unités .service correspondantes.
Où placer les fichiers
Section intitulée « Où placer les fichiers »L'emplacement du fichier détermine le mode d'exécution. Un répertoire situé
dans votre $HOME produit un service rootless géré par le systemd de votre
session ; un répertoire système produit un service rootful lancé par le
systemd de la machine. Toutes les commandes systemctl et journalctl
changent en conséquence, avec ou sans --user.
~/.config/containers/systemd/├── nginx.container├── data.volume└── app-network.networkCommandes avec --user :
systemctl --user daemon-reloadsystemctl --user start nginxjournalctl --user -u nginx/etc/containers/systemd/├── nginx.container├── data.volume└── app-network.networkCommandes sans --user :
sudo systemctl daemon-reloadsudo systemctl start nginxsudo journalctl -u nginxTypes de fichiers Quadlet
Section intitulée « Types de fichiers Quadlet »Quadlet reconnait plusieurs types de fichiers, chacun correspondant à un type de ressource Podman. L'extension du fichier détermine ce que Quadlet va créer :
| Extension | Ce qu'il définit | Équivalent Podman |
|---|---|---|
.container | Un conteneur | podman run |
.volume | Un volume nommé | podman volume create |
.network | Un réseau | podman network create |
.pod | Un pod | podman pod create |
.image | Une image à pull | podman pull |
.kube | Un play kube | podman kube play |
.build | Un build d'image | podman build |
Dans la pratique, vous utiliserez principalement .container, .volume et .network. Les autres types couvrent des cas d'usage plus spécifiques comme l'intégration avec des manifests Kubernetes (.kube) ou le build d'images en CI/CD (.build).
Voir ce qui est généré
Section intitulée « Voir ce qui est généré »Pour inspecter l'unité systemd générée à partir de votre fichier Quadlet :
# Rootlesssystemctl --user cat nginx.service
# Rootfulsystemctl cat nginx.serviceDémarrage en 5 minutes
Section intitulée « Démarrage en 5 minutes »Créons un serveur nginx comme service systemd.
-
Créer le répertoire Quadlet (rootless)
Fenêtre de terminal mkdir -p ~/.config/containers/systemd -
Créer le fichier
nginx.containerFenêtre de terminal cat > ~/.config/containers/systemd/nginx.container << 'EOF'[Unit]Description=Serveur web Nginx[Container]Image=docker.io/library/nginx:alpinePublishPort=8080:80[Service]Restart=always[Install]WantedBy=default.targetEOF -
Recharger systemd
Fenêtre de terminal systemctl --user daemon-reload -
Démarrer le service
Fenêtre de terminal systemctl --user start nginx -
Vérifier
Fenêtre de terminal systemctl --user status nginxRésultat ● nginx.service - Serveur web NginxLoaded: loaded (/home/bob/.config/containers/systemd/nginx.container; generated)Active: active (running) since Thu 2026-02-13 10:30:00 CET; 5s agoMain PID: 12345 (conmon)
Testez avec curl http://localhost:8080, vous devriez voir la page d'accueil nginx.
Activer au démarrage
Section intitulée « Activer au démarrage »enable crée le lien symbolique attendu par la cible déclarée dans la
section [Install]. Sans cette commande, le service existe mais ne démarre que
lorsque vous le lancez à la main.
systemctl --user enable nginxAnatomie d'un fichier Quadlet
Section intitulée « Anatomie d'un fichier Quadlet »Un fichier .container se compose de 4 sections :
[Unit]Description=Description du serviceAfter=network-online.target
[Container]Image=docker.io/library/nginx:alpinePublishPort=8080:80Volume=data:/var/www:ZEnvironment=MA_VAR=valeurReadOnly=true
[Service]Restart=alwaysTimeoutStartSec=300
[Install]WantedBy=default.targetSection [Unit]
Section intitulée « Section [Unit] »Cette section utilise la syntaxe standard systemd pour définir les métadonnées et les dépendances du service. Les directives les plus utiles :
| Directive | Usage |
|---|---|
Description= | Description affichée dans systemctl status |
After= | Démarre après ces unités |
Requires= | Dépendance forte (si l'autre échoue, celui-ci aussi) |
Wants= | Dépendance faible |
Astuce dépendances : utilisez Requires= pour les dépendances critiques (base de données pour une application) et Wants= pour les dépendances optionnelles (monitoring, logs). After= ne garantit que l'ordre de démarrage, pas que le service dépendant est fonctionnel.
Section [Container]
Section intitulée « Section [Container] »C'est le cœur de votre fichier Quadlet. Chaque directive correspond à une option de podman run, mais avec une syntaxe déclarative plus lisible :
| Directive Quadlet | Option podman run | Exemple |
|---|---|---|
Image= | (image) | nginx:alpine |
PublishPort= | -p | 8180:80 |
Volume= | -v | data:/app:Z |
Environment= | -e | DEBUG=true |
EnvironmentFile= | --env-file | /etc/myapp/env |
User= | --user | 1000:1000 |
ReadOnly= | --read-only | true |
AddCapability= | --cap-add | NET_BIND_SERVICE |
DropCapability= | --cap-drop | ALL |
SecurityLabelDisable= | --security-opt label=disable | true |
Network= | --network | app-network.network |
PodmanArgs= | (options supplémentaires) | --init --userns=keep-id |
Exec= | (commande) | /bin/sh -c "sleep infinity" |
AutoUpdate= | label auto-update | registry |
Deux directives essentielles :
PodmanArgs=: permet de passer des optionspodman runnon supportées directement par Quadlet. Utilisez-le pour--userns=keep-id(rootless) ou--security-opt.Network=: référence un fichier.networkdu même répertoire. Quadlet gère automatiquement l'ordre de création.
Section [Service]
Section intitulée « Section [Service] »Cette section contrôle le comportement systemd du service. Les paramètres les plus importants concernent la gestion des redémarrages et les timeouts :
| Directive | Usage | Valeur typique |
|---|---|---|
Restart= | Politique de restart | always, on-failure |
RestartSec= | Délai entre restarts | 5s |
TimeoutStartSec= | Timeout au démarrage | 300 (pour pull d'image) |
TimeoutStopSec= | Timeout à l'arrêt | 30 |
Pourquoi ces valeurs ?
Restart=always: en production, vous voulez que le service redémarre automatiquement après un crash ou un reboot.RestartSec=5s: évite les boucles de redémarrage rapide en cas de problème persistant.TimeoutStartSec=300: 5 minutes pour permettre le pull d'images lourdes (plusieurs Go).
Section [Install]
Section intitulée « Section [Install] »Définit quand le service doit démarrer :
[Install]WantedBy=default.target # rootless# ouWantedBy=multi-user.target # rootfulRecette 1, Service durci (production)
Section intitulée « Recette 1, Service durci (production) »Voici un service nginx prêt pour la production, avec les bonnes pratiques de sécurité :
[Unit]Description=Nginx productionAfter=network-online.target
[Container]Image=docker.io/library/nginx:alpinePublishPort=8080:80
# Sécurité : filesystem read-only + tmpfs pour les dossiers d'écritureReadOnly=trueTmpfs=/tmpTmpfs=/var/cache/nginxTmpfs=/var/run
# Sécurité : capabilities minimalesDropCapability=ALLAddCapability=NET_BIND_SERVICEAddCapability=CHOWNAddCapability=SETGIDAddCapability=SETUID
# Options supplémentaires via PodmanArgsPodmanArgs=--security-opt no-new-privileges --init
# Volume pour les données (lecture seule)Volume=web-content:/usr/share/nginx/html:ro,Z
[Service]Restart=alwaysRestartSec=5sTimeoutStartSec=300TimeoutStopSec=30
[Install]WantedBy=default.targetVérifications :
# Recharger et démarrersystemctl --user daemon-reloadsystemctl --user start nginx-prod
# Vérifier le statutsystemctl --user status nginx-prod
# Voir l'unité généréesystemctl --user cat nginx-prod.service
# Tester le restart automatiquepodman kill $(podman ps -q --filter name=systemd-nginx-prod)sleep 10systemctl --user status nginx-prod # Doit être "active (running)"Recette 2, Rootless propre
Section intitulée « Recette 2, Rootless propre »En mode rootless, quelques points d'attention :
Répertoire des fichiers
Section intitulée « Répertoire des fichiers »En rootless, Quadlet ne lit que ~/.config/containers/systemd/. Un fichier
correct placé ailleurs est purement et simplement ignoré, sans le moindre
message d'erreur : c'est la première chose à vérifier quand rien n'apparaît.
# Créer le répertoiremkdir -p ~/.config/containers/systemd
# Vos fichiers doivent être icils ~/.config/containers/systemd/Ports exposés
Section intitulée « Ports exposés »En rootless, vous ne pouvez pas exposer de ports < 1024 sans configuration spéciale :
# ❌ Ne fonctionne pas en rootlessPublishPort=80:80
# ✅ Port > 1024PublishPort=8080:80Volumes et permissions
Section intitulée « Volumes et permissions »Problème classique : le conteneur n'a pas accès aux fichiers de l'hôte.
Solution 1 : utiliser PodmanArgs=--userns=keep-id
[Container]Image=nginx:alpineVolume=./html:/usr/share/nginx/html:ZPodmanArgs=--userns=keep-idSolution 2 : utiliser le suffixe :U (chown automatique)
[Container]Volume=myvolume:/data:UQuand basculer en rootful
Section intitulée « Quand basculer en rootful »Le mode rootless est le choix par défaut pour la sécurité (pas de privilèges root). Cependant, certaines situations nécessitent le mode rootful :
| Situation | Rootless | Rootful |
|---|---|---|
| Dev local | ✅ | |
| Service utilisateur | ✅ | |
| Port < 1024 nécessaire | ✅ | |
| Accès hardware (GPU, USB) | ✅ | |
| Performance réseau critique | ✅ | |
| Service système partagé | ✅ |
Règle de décision : commencez toujours en rootless. Basculez en rootful uniquement si vous avez une contrainte technique (port 80/443, GPU) ou organisationnelle (service partagé entre utilisateurs). Le passage en rootful se fait en plaçant vos fichiers dans /etc/containers/systemd/ au lieu de ~/.config/containers/systemd/.
Recette 3, Stack multi-services
Section intitulée « Recette 3, Stack multi-services »Créons une stack complète : PostgreSQL + application web, avec volume et réseau dédiés.
Structure des fichiers
Section intitulée « Structure des fichiers »Quatre fichiers dans un même répertoire suffisent à décrire la stack
complète. Quadlet reconstruit lui-même l'ordre de création à partir des
références croisées entre fichiers : il n'y a pas de fichier d'orchestration
global à écrire, contrairement à un compose.yaml.
Répertoire~/.config/containers/systemd/
- app-network.network
- pgdata.volume
- postgres.container
- webapp.container
1. Créer le réseau
Section intitulée « 1. Créer le réseau »Le réseau est déclaré avec un sous-réseau fixe, ce qui rend les adresses
prévisibles d'un redémarrage à l'autre. La section [Network] accepte les mêmes
options que podman network create.
[Unit]Description=Réseau applicatif
[Network]Subnet=10.89.0.0/24Gateway=10.89.0.12. Créer le volume
Section intitulée « 2. Créer le volume »Un fichier .volume peut se réduire à une section [Volume] vide : les
valeurs par défaut de Podman conviennent dans la plupart des cas. L'intérêt du
fichier est ailleurs, il rend le volume déclaratif et permet aux conteneurs
de le référencer comme une dépendance.
[Unit]Description=Données PostgreSQL
[Volume]# Options par défaut suffisent3. Créer le service PostgreSQL
Section intitulée « 3. Créer le service PostgreSQL »Ce fichier réunit les trois briques : le réseau, le volume et un
healthcheck, cette dernière directive permettant à Podman de vérifier
périodiquement que la base répond vraiment. Le mot de passe apparaît ici en
clair pour la lisibilité de l'exemple ; en production, sortez-le dans un fichier
en mode 0600 référencé par EnvironmentFile=.
[Unit]Description=Base de données PostgreSQLAfter=app-network.network pgdata.volume
[Container]Image=docker.io/library/postgres:16-alpineNetwork=app-network.networkVolume=pgdata.volume:/var/lib/postgresql/data:Z
# Variables d'environnementEnvironment=POSTGRES_USER=appEnvironment=POSTGRES_PASSWORD=secretEnvironment=POSTGRES_DB=myapp
# HealthcheckHealthCmd=pg_isready -U app -d myappHealthInterval=10sHealthTimeout=5sHealthRetries=3
[Service]Restart=alwaysTimeoutStartSec=300
[Install]WantedBy=default.target4. Créer le service application
Section intitulée « 4. Créer le service application »L'application déclare Requires= en plus de After= : elle refuse donc de
démarrer si PostgreSQL n'a pas démarré, au lieu de boucler sur des erreurs de
connexion. Repérez aussi le nom d'hôte systemd-postgres dans l'URL de
connexion, conséquence directe du préfixe que Quadlet applique à tous les
conteneurs qu'il crée.
[Unit]Description=Application webAfter=postgres.containerRequires=postgres.container
[Container]Image=docker.io/myapp:latestNetwork=app-network.networkPublishPort=8080:3000
Environment=DATABASE_URL=postgres://app:secret@systemd-postgres:5432/myapp
PodmanArgs=--init --userns=keep-id
[Service]Restart=alwaysRestartSec=5s
[Install]WantedBy=default.targetDéployer la stack
Section intitulée « Déployer la stack »Une seule commande de démarrage suffit : systemd résout les dépendances et
met en place le réseau, le volume puis PostgreSQL avant de lancer webapp.
# Rechargersystemctl --user daemon-reload
# Démarrer (l'ordre est géré par les dépendances)systemctl --user start webapp
# Vérifiersystemctl --user status app-network pgdata postgres webappPoints clés
Section intitulée « Points clés »Cette stack illustre plusieurs mécanismes Quadlet importants :
| Directive | Ce qu'elle fait |
|---|---|
After=postgres.container | Démarre après PostgreSQL |
Requires=postgres.container | Si PostgreSQL échoue, webapp s'arrête |
Network=app-network.network | Utilise le réseau Quadlet |
Volume=pgdata.volume:/path | Utilise le volume Quadlet |
Comment Quadlet gère les ressources : quand vous référencez app-network.network dans Network=, Quadlet sait que c'est un fichier du même répertoire. Il crée le réseau systemd-app-network avant de démarrer le conteneur. Même logique pour les volumes.
Attention : les fichiers .network et .volume ne créent pas de services systemd visibles avec systemctl status. Ils créent les ressources Podman sous-jacentes (vérifiez avec podman network ls et podman volume ls).
Bonnes pratiques
Section intitulée « Bonnes pratiques »Les conventions rassemblées ici viennent de l'exploitation, pas de la
documentation de référence. Elles portent sur quatre points : le nommage,
la politique de redémarrage, l'ordre de démarrage et le durcissement du
conteneur. Chacune se traduit par quelques lignes ajoutées au fichier
.container, sans outil supplémentaire.
Un bon nommage facilite le debug et la maintenance à long terme :
- Fichiers : noms explicites (
postgres.container, pasdb.container). Quand vous aurez 10 services, vous regretterez les noms génériques. - Descriptions : rédigez-les pour
systemctl status. "Base de données PostgreSQL 16 - production" est plus utile que "db". - Un service = un fichier : Quadlet gère les dépendances entre fichiers. Évitez de tout mettre dans un seul fichier complexe.
Restart et timeouts
Section intitulée « Restart et timeouts »Les valeurs par défaut de systemd sont trop courtes pour un conteneur qui doit d'abord télécharger son image. Le bloc suivant donne un jeu de réglages utilisable tel quel en production.
[Service]# Toujours redémarrer en productionRestart=always
# Délai entre les redémarrages (évite les boucles)RestartSec=5s
# Timeout pour le pull d'image (images lourdes)TimeoutStartSec=300
# Timeout pour l'arrêt propreTimeoutStopSec=30Ordre de démarrage
Section intitulée « Ordre de démarrage »Requires= et After= répondent à deux questions distinctes, et les
confondre est l'erreur classique : la première porte sur la criticité de la
dépendance, la seconde uniquement sur la chronologie du démarrage. Un
service peut donc démarrer après un autre sans dépendre de sa réussite.
[Unit]# Dépendance forte : si postgres échoue, webapp ne démarre pasRequires=postgres.container
# Ordre : webapp démarre APRÈS postgresAfter=postgres.container
# Dépendance faible : si le réseau n'existe pas, on essaie quand mêmeWants=app-network.networkSécurité
Section intitulée « Sécurité »Ces directives réduisent ce que le conteneur peut faire s'il est compromis : plus d'écriture sur son propre système de fichiers, aucune capability Linux conservée hormis celle qui permet d'écouter sur un port privilégié, et interdiction d'acquérir de nouveaux privilèges en cours d'exécution.
[Container]# Filesystem en lecture seuleReadOnly=trueTmpfs=/tmp
# Capabilities minimalesDropCapability=ALLAddCapability=NET_BIND_SERVICE
# Bloquer l'escalade de privilègesPodmanArgs=--security-opt no-new-privileges --initObservabilité
Section intitulée « Observabilité »L'un des grands avantages de Quadlet : vos conteneurs bénéficient automatiquement de l'infrastructure de logs systemd. Plus besoin de podman logs, utilisez journalctl :
# Statut rapide (conteneur actif ? PID ? mémoire ?)systemctl --user status webapp
# Logs en temps réel (équivalent de podman logs -f)journalctl --user -u webapp -f
# Logs depuis le dernier boot (utile après un redémarrage)journalctl --user -u webapp -b
# Logs des 10 dernières minutes (debug incident récent)journalctl --user -u webapp --since "10 minutes ago"Avantage journalctl : les logs persistent après l'arrêt du conteneur et sont automatiquement rotatés par systemd.
Dépannage
Section intitulée « Dépannage »Quatre symptômes couvrent la quasi-totalité des blocages rencontrés avec Quadlet. Leur point commun est le silence : un fichier mal placé ou mal nommé ne provoque aucune erreur, il est simplement ignoré par le générateur, ce qui rend le diagnostic déroutant la première fois.
"Je pose le fichier mais rien n'apparaît"
Section intitulée « "Je pose le fichier mais rien n'apparaît" »C'est de loin le cas le plus fréquent. Déroulez les quatre vérifications dans l'ordre : la dernière confirme que systemd a effectivement pris le fichier en compte et généré une unité.
-
Vérifiez le répertoire
Fenêtre de terminal # Rootlessls ~/.config/containers/systemd/# Rootfulls /etc/containers/systemd/ -
Vérifiez l'extension
Le fichier doit se terminer par
.container,.volume,.network, etc. -
Rechargez systemd
Fenêtre de terminal systemctl --user daemon-reload -
Vérifiez que l'unité existe
Fenêtre de terminal systemctl --user list-unit-files | grep monservice
"Le service démarre puis s'arrête"
Section intitulée « "Le service démarre puis s'arrête" »Cause 1 : image inexistante
# Vérifier les logsjournalctl --user -u monservice -n 50
# Si l'image n'existe pas, la pull manuellementpodman pull docker.io/library/nginx:alpineCause 2 : port déjà utilisé
# Vérifier quel processus utilise le portss -tlnp | grep 8080Cause 3 : problème de permissions
# Logs détaillésjournalctl --user -u monservice --no-pager
# Chercher "permission denied""Rootless + volumes = permission denied"
Section intitulée « "Rootless + volumes = permission denied" »Solution 1 : ajouter --userns=keep-id
[Container]PodmanArgs=--userns=keep-idVolume=./data:/app/data:ZSolution 2 : utiliser le suffixe :U
[Container]Volume=myvolume:/app/data:USolution 3 : sur SELinux, ajouter :Z
[Container]Volume=./data:/app/data:Z"Le conteneur ne se connecte pas à la base de données"
Section intitulée « "Le conteneur ne se connecte pas à la base de données" »Vérifiez le nommage : Quadlet préfixe les conteneurs avec systemd-
# ❌ IncorrectEnvironment=DATABASE_HOST=postgres
# ✅ CorrectEnvironment=DATABASE_HOST=systemd-postgresCommandes de debug
Section intitulée « Commandes de debug »--dryrun est la commande la plus utile de la liste. Elle affiche sur la
sortie standard les unités que Quadlet produirait, sans rien écrire sur le
disque, ce qui rend immédiatement visible une directive mal orthographiée ou
refusée.
# Voir l'unité généréesystemctl --user cat monservice.service
# Tester la génération Quadlet manuellement/usr/libexec/podman/quadlet --dryrun --user
# Voir les logs systemd pour Quadletjournalctl --user -u systemd-generator -bTemplates prêts à copier
Section intitulée « Templates prêts à copier »Ces templates couvrent les cas d'usage courants. Copiez-les, adaptez Image= et PublishPort=, et vous avez un service fonctionnel.
Template conteneur simple
Section intitulée « Template conteneur simple »Le minimum viable pour démarrer rapidement. Adapté au développement local :
[Unit]Description=Mon service
[Container]Image=docker.io/library/nginx:alpinePublishPort=8080:80
[Service]Restart=always
[Install]WantedBy=default.targetTemplate conteneur durci
Section intitulée « Template conteneur durci »Pour la production : filesystem read-only, capabilities minimales, pas d'escalade de privilèges. Utilisez ce template comme base pour tout service exposé au réseau :
[Unit]Description=Service durci
[Container]Image=docker.io/library/nginx:alpinePublishPort=8080:80
ReadOnly=trueTmpfs=/tmpTmpfs=/var/run
DropCapability=ALLAddCapability=NET_BIND_SERVICE
PodmanArgs=--security-opt no-new-privileges --init --userns=keep-id
[Service]Restart=alwaysRestartSec=5sTimeoutStartSec=300
[Install]WantedBy=default.targetTemplate avec volume et réseau
Section intitulée « Template avec volume et réseau »Pour les services stateful (bases de données, caches). Ce template nécessite des fichiers .network et .volume complémentaires dans le même répertoire :
[Unit]Description=Service avec données persistantesAfter=mynetwork.network mydata.volume
[Container]Image=docker.io/library/postgres:16-alpineNetwork=mynetwork.networkVolume=mydata.volume:/var/lib/postgresql/data:Z
Environment=POSTGRES_PASSWORD=secret
HealthCmd=pg_isreadyHealthInterval=30s
[Service]Restart=alwaysTimeoutStartSec=300
[Install]WantedBy=default.targetMettre en pratique
Section intitulée « Mettre en pratique »C'est en écrivant votre propre fichier .container que Quadlet devient un réflexe : ce lab vous fait déclarer un conteneur comme service systemd, l'activer au boot et vérifier qu'il redémarre bien avec la machine.
À retenir
Section intitulée « À retenir »- Quadlet = fichiers déclaratifs (
.container,.volume,.network) → systemd gère le cycle de vie - Répertoires :
~/.config/containers/systemd/(rootless) ou/etc/containers/systemd/(rootful) - Workflow : créer fichier →
daemon-reload→start→status - Dépendances :
After=pour l'ordre,Requires=pour la criticité - Nommage : Quadlet préfixe avec
systemd-(important pour les connexions réseau) - Debug :
systemctl catpour voir l'unité générée,journalctlpour les logs