
Quand vous travaillez avec des conteneurs, vous passez la majorité de votre temps à lancer des conteneurs, consulter leurs logs, exécuter des commandes dedans et nettoyer les ressources. Podman est un moteur de conteneurs rootless compatible Docker qui vous permet de gérer images et conteneurs sans privilèges root.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Rechercher, télécharger et gérer des images
- Lancer des conteneurs en avant-plan et arrière-plan
- Interagir avec des conteneurs en cours d'exécution (exec, logs, cp)
- Exposer des ports et monter des volumes
- Diagnostiquer et nettoyer vos ressources
La commande podman dans l'écosystème conteneurs
Section intitulée « La commande podman dans l'écosystème conteneurs »Podman fait partie d'un écosystème d'outils complémentaires. Chaque outil a sa spécialité :
| Commande | Spécialité | Quand l'utiliser |
|---|---|---|
podman | Exécuter et gérer les conteneurs | run, ps, exec, logs, stop, rm |
buildah | Construire des images | Build avancé, multi-stage, rootless |
skopeo | Copier des images entre registries | Mirroring, air-gap, inspection |
podman-compose | Orchestrer plusieurs conteneurs | Stack multi-conteneurs (comme docker-compose) |
Combinaisons fréquentes :
# buildah + podman : construire puis lancerbuildah build -t mon-app . && podman run mon-app
# skopeo + podman : copier puis exécuterskopeo copy docker://nginx:alpine oci-archive:nginx.tarpodman load < nginx.tar && podman run nginx:alpine
# podman + grep : filtrer les logspodman logs mon-app | grep ERRORComprendre Podman en 2 min
Section intitulée « Comprendre Podman en 2 min »Avant les commandes, un modèle mental. Podman ne s'appuie sur aucun daemon :
chaque podman run démarre directement le processus du conteneur sous votre
compte utilisateur. C'est la différence structurelle avec Docker, et elle
explique la plupart des écarts de comportement que vous rencontrerez, à
commencer par ceux du mode rootless.
🧠 Modèle mental — Comment fonctionne Podman
podman = Image → Conteneur → Processus isolé (rootless par défaut)
Points clés
- Une image est un modèle en lecture seule (template)
- Un conteneur est une instance exécutable d'une image
- Chaque conteneur est un processus isolé supervisé par conmon
- Mode rootless par défaut = pas de privilèges root nécessaires
- Les données sont perdues à la suppression du conteneur (sauf volumes)
- Les commandes sont compatibles Docker (alias docker=podman)
Règles d'or
Vocabulaire essentiel
- image
- Modèle en lecture seule contenant l'application et ses dépendances
- conteneur
- Instance exécutable d'une image (processus isolé)
- registry
- Serveur qui stocke et distribue les images (Docker Hub, Quay.io)
- tag
- Version ou variante d'une image (alpine:3.20, nginx:1.25)
- volume
- Stockage persistant indépendant du cycle de vie du conteneur
- port mapping
- Liaison port hôte → port conteneur (-p 8080:80)
📚 Pour aller plus loin — 8 options avancées
- rootless
- Exécution sans privilèges root (user namespaces)
- conmon
- Superviseur léger qui maintient le conteneur
- pod
- Groupe de conteneurs partageant le même namespace réseau
- bind mount
- Montage direct d'un dossier hôte dans le conteneur
- overlay
- Système de fichiers en couches pour les images
- entrypoint
- Commande par défaut exécutée au démarrage du conteneur
- CMD
- Arguments par défaut passés à l'entrypoint
- namespace
- Isolation des ressources (PID, network, mount, user)
Contrairement à Docker qui nécessite un daemon root, Podman exécute chaque conteneur comme un processus indépendant supervisé par conmon. C'est rootless par défaut.
Syntaxe complète
Section intitulée « Syntaxe complète »Toutes les commandes suivent la même forme. L'ordre des éléments compte : ce qui est placé après le nom de l'image est transmis au conteneur, pas à Podman.
podman <commande> [options] [arguments]Commandes les plus utilisées :
| Commande | Description | Exemple |
|---|---|---|
run | Créer et démarrer un conteneur | podman run -d nginx |
ps | Lister les conteneurs | podman ps -a |
exec | Exécuter une commande dans un conteneur | podman exec -it web sh |
logs | Afficher les logs | podman logs -f web |
stop / start | Arrêter / démarrer un conteneur | podman stop web |
rm | Supprimer un conteneur | podman rm web |
images | Lister les images | podman images |
pull | Télécharger une image | podman pull alpine:3.20 |
Les concepts clés
Section intitulée « Les concepts clés »Podman repose sur quelques concepts essentiels :
| Concept | Ce que c'est | Exemple |
|---|---|---|
| Image | Modèle en lecture seule | nginx:alpine, alpine:3.20 |
| Conteneur | Instance exécutable d'une image | podman run nginx crée un conteneur |
| Registry | Serveur de distribution d'images | Docker Hub, Quay.io, GHCR |
| Volume | Stockage persistant | podman run -v data:/app/data |
| Port mapping | Exposition réseau | podman run -p 8080:80 |
Les options essentielles de run
Section intitulée « Les options essentielles de run »La commande podman run est la plus utilisée. Voici ses options principales :
| Option | Forme longue | Description |
|---|---|---|
-d | --detach | Exécuter en arrière-plan |
-it | --interactive --tty | Mode interactif avec terminal |
--rm | Supprimer après arrêt | |
--name | Nommer le conteneur | |
-p | --publish | Mapper un port hôte:conteneur |
-e | --env | Définir une variable d'environnement |
-v | --volume | Monter un volume |
Formes courantes :
# Conteneur jetable interactifpodman run -it --rm alpine:3.20 sh
# Service en arrière-planpodman run -d --name web -p 8080:80 nginx:alpine
# Avec volume et variable d'environnementpodman run -d --name db -v pgdata:/var/lib/postgresql/data \ -e POSTGRES_PASSWORD=secret postgres:16Cycle de vie d'un conteneur
Section intitulée « Cycle de vie d'un conteneur »Un conteneur passe par plusieurs états :
Created → Running → Paused/Exited → Removed| État | Signification | Commande pour y arriver |
|---|---|---|
| Created | Conteneur créé mais pas démarré | podman create |
| Running | En cours d'exécution | podman start ou podman run |
| Paused | Processus gelés (SIGSTOP) | podman pause |
| Exited | Arrêté (code de sortie) | podman stop ou fin du processus |
| Removed | Supprimé | podman rm |
Erreurs typiques (et solutions)
Section intitulée « Erreurs typiques (et solutions) »Ces cinq messages représentent la quasi-totalité des blocages en début d'utilisation. Chacun est repris en détail dans la partie consacrée aux pièges ; ce tableau sert de référence rapide quand vous avez le message sous les yeux.
| Erreur | Cause | Solution |
|---|---|---|
name already in use | Conteneur existant avec ce nom | podman rm -f nom ou --replace |
image not known | Image non téléchargée | podman pull docker.io/library/image:tag |
address already in use | Port déjà utilisé | Changer le port (-p 8081:80) |
permission denied | Problème rootless/SELinux | --userns=keep-id ou :Z sur volume |
| Conteneur s'arrête immédiatement | CMD se termine | Utiliser un processus persistant |
Gestion des images
Section intitulée « Gestion des images »Une image est un modèle en lecture seule contenant l'application et ses dépendances.
Rechercher et télécharger
Section intitulée « Rechercher et télécharger »podman search liste des dépôts, pas des versions : ajoutez --list-tags
pour connaître les tags disponibles avant de choisir celui à télécharger. Un
podman pull sans tag récupère implicitement :latest.
# Rechercher une imagepodman search docker.io/alpine --limit 3
# Télécharger une image (avec tag explicite)podman pull docker.io/library/alpine:3.20
# Lister les images localespodman imagesRésultat podman images :
REPOSITORY TAG IMAGE ID CREATED SIZEdocker.io/library/alpine 3.20 cc9071bd1610 2 weeks ago 8.1 MBdocker.io/library/nginx alpine b76de378d572 8 days ago 63.5 MBInspecter et supprimer
Section intitulée « Inspecter et supprimer »podman image inspect renvoie un JSON complet ; --format accepte un template
Go pour n'extraire que les champs voulus. Attention à podman image prune -a :
il supprime toute image qu'aucun conteneur n'utilise, y compris celles que
vous venez de télécharger.
# Détails d'une image (format Go template)podman image inspect alpine:3.20 --format 'ID: {{.Id}} | Size: {{.Size}}'
# Supprimer une imagepodman rmi alpine:3.20
# Supprimer toutes les images non utiliséespodman image prune -aExécution de conteneurs
Section intitulée « Exécution de conteneurs »Trois façons de lancer un conteneur couvrent la quasi-totalité des besoins : au
premier plan pour une commande ponctuelle, en arrière-plan pour un
service, en interactif pour explorer une image. Le choix se joue sur deux
options seulement, -d et -it.
Conteneur simple (avant-plan)
Section intitulée « Conteneur simple (avant-plan) »Sans option, Podman rattache la sortie du conteneur à votre terminal et attend la fin du processus avant de rendre la main.
podman run docker.io/library/alpine:3.20 echo "Hello Podman"Le conteneur exécute la commande, affiche le résultat, puis s'arrête.
Conteneur en arrière-plan
Section intitulée « Conteneur en arrière-plan »L'option -d rend la main immédiatement et affiche l'identifiant du conteneur
créé, qui devient le moyen de le retrouver si vous ne l'avez pas nommé.
podman run -d --name mon-nginx -p 8080:80 docker.io/library/nginx:alpine| Option | Description |
|---|---|
-d | Détaché (arrière-plan) |
--name mon-nginx | Nom explicite pour référencer facilement |
-p 8080:80 | Port 8080 sur l'hôte → port 80 du conteneur |
Vérification :
curl localhost:8080Conteneur interactif
Section intitulée « Conteneur interactif »La combinaison -it est indispensable pour obtenir un shell utilisable : sans
-t, aucune invite ni gestion des touches ; sans -i, votre clavier n'est pas
transmis au conteneur.
podman run -it --rm docker.io/library/alpine:3.20 shVous obtenez un shell dans le conteneur. Tapez exit pour quitter. --rm supprime le conteneur à la sortie.
Lister et inspecter
Section intitulée « Lister et inspecter »Deux besoins distincts se présentent : savoir ce qui tourne, et savoir comment
un conteneur précis est configuré. La première question se règle avec
podman ps, la seconde avec podman inspect, qui expose l'intégralité de la
configuration au format JSON.
Lister les conteneurs
Section intitulée « Lister les conteneurs »podman ps n'affiche que les conteneurs actifs. Les conteneurs arrêtés
existent toujours : ils continuent d'occuper leur nom et leur espace disque tant
qu'ils ne sont pas supprimés.
# Conteneurs en cours d'exécutionpodman ps
# Tous les conteneurs (y compris arrêtés)podman ps -a
# Format personnalisépodman ps --format "{{.Names}}: {{.Image}} ({{.Status}})"Inspecter un conteneur
Section intitulée « Inspecter un conteneur »podman inspect renvoie plusieurs centaines de lignes de JSON, d'où l'intérêt
de --format pour cibler un seul champ. Les commandes podman top et
podman port donnent en revanche des vues déjà lisibles : processus en cours et
ports publiés.
# Configuration complète (JSON)podman inspect mon-nginx
# Extraire un champ spécifique (état, image...)podman inspect --format '{{.State.Status}}' mon-nginx
# Voir les processuspodman top mon-nginx
# Voir les ports exposéspodman port mon-nginxInteragir avec un conteneur
Section intitulée « Interagir avec un conteneur »Une fois le conteneur démarré, trois opérations reviennent en permanence : lancer une commande à l'intérieur, lire ce qu'il écrit, et échanger des fichiers avec lui. Aucune n'oblige à arrêter le conteneur ni à reconstruire son image.
Exécuter une commande
Section intitulée « Exécuter une commande »podman exec s'adresse à un conteneur déjà en cours d'exécution et échoue
sur un conteneur arrêté. Il lance un processus supplémentaire : il ne remplace
pas le processus principal du conteneur.
# Commande simplepodman exec mon-nginx cat /etc/nginx/nginx.conf
# Shell interactifpodman exec -it mon-nginx sh
# En tant que root (même en rootless)podman exec -u root mon-nginx whoamiConsulter les logs
Section intitulée « Consulter les logs »podman logs restitue ce que le conteneur a écrit sur sa sortie standard et
sa sortie d'erreur. Une application qui journalise dans un fichier interne
n'apparaîtra donc pas ici, quel que soit le nombre d'options ajoutées.
# Tous les logspodman logs mon-nginx
# Dernières 20 lignespodman logs --tail 20 mon-nginx
# Suivre en temps réel (comme tail -f)podman logs -f mon-nginx
# Avec timestampspodman logs -t mon-nginxCopier des fichiers
Section intitulée « Copier des fichiers »podman cp fonctionne dans les deux sens et même sur un conteneur arrêté.
podman diff complète utilement la manipulation : il liste ce qui a été ajouté,
modifié ou supprimé par rapport à l'image d'origine.
# Vers le conteneurpodman cp config.yml mon-nginx:/etc/nginx/
# Depuis le conteneurpodman cp mon-nginx:/etc/nginx/nginx.conf ./backup/
# Vérifier les modifications du filesystempodman diff mon-nginxContrôler le cycle de vie
Section intitulée « Contrôler le cycle de vie »Ces commandes déplacent un conteneur d'un état à l'autre sans le détruire. La
distinction entre stop et kill est celle qui compte : le premier envoie
SIGTERM et laisse l'application se fermer proprement avant de forcer, le
second envoie directement SIGKILL et coupe tout traitement en cours.
# Arrêter (SIGTERM puis SIGKILL après timeout)podman stop mon-nginx
# Arrêter immédiatement (SIGKILL)podman kill mon-nginx
# Redémarrerpodman restart mon-nginx
# Démarrer un conteneur arrêtépodman start mon-nginx
# Mettre en pause / reprendrepodman pause mon-nginxpodman unpause mon-nginxSurveillance et statistiques
Section intitulée « Surveillance et statistiques »podman stats se rafraîchit en continu jusqu'à interruption ; --no-stream en
donne un instantané, seule forme exploitable dans un script. podman system df
répond à une autre question, celle de l'espace disque consommé par les
images, les conteneurs et les volumes.
# Statistiques en temps réelpodman stats
# Snapshot (sans rafraîchissement)podman stats --no-stream
# Espace disque utilisépodman system dfExemple de sortie podman stats (Podman 5.8, colonnes enrichies) :
ID NAME CPU % MEM USAGE / LIMIT MEM % NET IO BLOCK IO PIDS CPU TIME AVG CPU %a79693ad4f28 mon-nginx 0.04% 10.89MB / 3.82GB 0.28% 110B / 430B 0B / 0B 17 42ms 0.03%Nettoyage des ressources
Section intitulée « Nettoyage des ressources »Les conteneurs arrêtés ne disparaissent pas d'eux-mêmes, sauf s'ils ont été
lancés avec --rm. Sur un poste de développement, ils s'accumulent avec leur
couche d'écriture et finissent par peser lourd, d'où les commandes de nettoyage
groupé ci-dessous.
# Supprimer un conteneur arrêtépodman rm mon-nginx
# Forcer la suppression (même si running)podman rm -f mon-nginx
# Supprimer tous les conteneurs arrêtéspodman rm $(podman ps -aq --filter status=exited)
# Nettoyage automatique (conteneurs + images non utilisées)podman system prune
# Nettoyage complet (inclut volumes orphelins)podman system prune -a --volumes -fSauvegarder et transférer
Section intitulée « Sauvegarder et transférer »Ces commandes servent aux environnements privés de registre : save et load
transportent une image sous forme de fichier tar. podman commit fige l'état
d'un conteneur dans une nouvelle image, ce qui dépanne mais reste à proscrire
pour produire une image de production, dont l'origine doit rester reproductible
depuis un Containerfile.
# Exporter une image en archive tarpodman save docker.io/library/alpine:3.20 -o alpine.tar
# Importer une archivepodman load -i alpine.tar
# Taguer une image (créer un alias)podman tag alpine:3.20 mon-registre/alpine:stable
# Exporter un conteneur en imagepodman commit mon-nginx mon-nginx-custom:v1Les patterns de commandes courants
Section intitulée « Les patterns de commandes courants »Maintenant que vous comprenez les commandes de base, voici des recettes prêtes à l'emploi pour les usages les plus fréquents. Chacune associe une formule générique et un exemple concret à adapter.
Conteneur interactif jetable
Section intitulée « Conteneur interactif jetable »Tester une commande ou explorer une image, sans rien laisser derrière.
# Formulepodman run -it --rm <image> <shell>
# Exemplepodman run -it --rm alpine:3.20 sh-it: interactif avec TTY ;--rm: supprime le conteneur à l'arrêt.
Service en arrière-plan
Section intitulée « Service en arrière-plan »Lancer un service qui tourne en continu.
# Formulepodman run -d --name <nom> <image>
# Exemplepodman run -d --name mon-nginx nginx:alpine-d: mode détaché ;--name: nomme le conteneur pour le retrouver facilement.
Exposer un port
Section intitulée « Exposer un port »Rendre un service accessible depuis l'hôte.
# Formulepodman run -d -p <hôte>:<conteneur> <image>
# Exemplepodman run -d -p 8080:80 --name web nginx:alpine-p 8080:80: mappe le port 8080 de l'hôte sur le port 80 du conteneur.
Monter un dossier
Section intitulée « Monter un dossier »Partager des fichiers entre l'hôte et le conteneur.
# Formulepodman run -v <chemin_hôte>:<chemin_conteneur> <image>
# Exemplepodman run -v ~/data:/app/data:Z alpine ls /app/data:Z: relabeling SELinux ;:ro: montage en lecture seule.
Variables d'environnement
Section intitulée « Variables d'environnement »Configurer l'application via son environnement.
# Formulepodman run -e VAR=valeur <image>
# Exemplepodman run -e POSTGRES_PASSWORD=secret -e POSTGRES_DB=app postgres:16-e VAR=val: définit une variable ;--env-file: charge depuis un fichier.
Debug dans un conteneur
Section intitulée « Debug dans un conteneur »Inspecter un conteneur déjà en cours d'exécution.
# Formulepodman exec -it <conteneur> <shell>
# Exemplepodman exec -it mon-nginx sh-it: interactif avec TTY ;-u root: exécute en tant que root.
Suivre les logs en temps réel
Section intitulée « Suivre les logs en temps réel »Monitorer l'activité d'un conteneur.
# Formulepodman logs -f <conteneur>
# Exemplepodman logs -f --tail 50 mon-nginx-f: suit en temps réel ;--tail N: limite aux N dernières lignes ;-t: affiche les timestamps.
Nettoyage complet
Section intitulée « Nettoyage complet »Supprimer toutes les ressources inutilisées et libérer de l'espace.
# Formulepodman system prune -a
# Exemplepodman system prune -a --volumes -f-a: inclut les images non utilisées ;--volumes: inclut les volumes orphelins ;-f: sans confirmation.
Extraire des infos avec --format
Section intitulée « Extraire des infos avec --format »Obtenir une information précise d'un conteneur, utile en scripting.
# Formulepodman inspect --format '{{.Field}}' <conteneur>
# Exemplepodman inspect --format '{{.State.Status}}' mon-nginx--format: template Go ;{{.State.Status}}: état du conteneur. En rootless, préférezpodman portà{{.NetworkSettings.IPAddress}}(vide par défaut).
Limiter les ressources
Section intitulée « Limiter les ressources »Contrôler la consommation CPU et mémoire d'un conteneur.
# Formulepodman run --memory=<limit> --cpus=<N> <image>
# Exemplepodman run -d --memory=512m --cpus=1 --name limited nginx:alpine--memory: limite mémoire (512m,1g) ;--cpus: nombre de CPUs ;--pids-limit: nombre de processus.
Vérification de santé
Section intitulée « Vérification de santé »Surveiller automatiquement la santé d'un service.
# Formulepodman run --health-cmd="<cmd>" --health-interval=<durée> <image>
# Exemplepodman run -d --health-cmd="curl -f http://localhost/" --health-interval=30s nginx:alpine--health-cmd: commande de vérification ;--health-interval: intervalle entre les contrôles.
Copier des fichiers
Section intitulée « Copier des fichiers »Transférer des fichiers depuis ou vers un conteneur.
# Formulepodman cp <src> <dest>
# Exemplepodman cp mon-nginx:/etc/nginx/nginx.conf ./backup/- La syntaxe
conteneur:chemindésigne un emplacement dans le conteneur.
Les pièges à éviter
Section intitulée « Les pièges à éviter »Ces erreurs reviennent constamment avec Podman. Plusieurs touchent la persistance des données ou le mode rootless : les connaître évite des pertes et des blocages.
Nom de conteneur déjà utilisé
Section intitulée « Nom de conteneur déjà utilisé »Un nom reste réservé jusqu'à la suppression effective du conteneur : podman stop ne le libère pas.
podman run --name mon-app imageSymptôme : erreur container name is already in use.
Cause : un conteneur, même arrêté, existe déjà avec ce nom.
podman rm -f mon-app && podman run --name mon-app image# ou directementpodman run --replace --name mon-app imageImage non trouvée
Section intitulée « Image non trouvée »Podman ne consulte pas Docker Hub d'office. La liste des registres interrogés
est celle de /etc/containers/registries.conf, et un nom d'image sans domaine
peut donc rester introuvable.
podman run alpineSymptôme : erreur image not known ou manifest unknown.
Cause : Podman ne trouve pas l'image dans ses registres configurés.
podman pull docker.io/library/alpine:3.20podman run docker.io/library/alpine:3.20Port déjà utilisé
Section intitulée « Port déjà utilisé »Le conflit porte sur le port de l'hôte, à gauche du deux-points. Le port du conteneur, à droite, peut être identique sur plusieurs conteneurs sans poser de problème.
podman run -p 8080:80 nginxSymptôme : erreur bind: address already in use.
Cause : un autre processus ou conteneur occupe déjà ce port.
# Trouver qui utilise le portss -tlnp | grep 8080# Utiliser un autre portpodman run -p 8081:80 nginxPermission denied sur un volume
Section intitulée « Permission denied sur un volume »En rootless, votre UID de l'hôte devient l'UID 0 à l'intérieur du conteneur, et
les autres utilisateurs du conteneur tombent dans une plage subuid qui n'a
aucun droit sur vos fichiers.
podman run -v ~/data:/app/data imageSymptôme : erreur de permission sur les fichiers montés.
Cause : le mapping d'UID en mode rootless ou SELinux bloque l'accès.
podman run --userns=keep-id -v ~/data:/app/data image# ou avec SELinuxpodman run -v ~/data:/app/data:Z imageUtilisation de :latest
Section intitulée « Utilisation de :latest »Une image citée sans tag est complétée implicitement par :latest, qui n'est
pas un numéro de version mais un simple alias déplaçable par le mainteneur.
podman run nginxSymptôme : le comportement change après un pull.
Cause : :latest n'est pas une version fixe, elle évolue sans prévenir. Spécifiez toujours un tag de version explicite.
podman run nginx:1.25-alpinePerte de données sans volume
Section intitulée « Perte de données sans volume »Vous lancez postgres, puis supprimez le conteneur avec podman rm.
Symptôme : les données disparaissent à la suppression du conteneur.
Cause : les données écrites dans le conteneur sont éphémères.
podman run -v postgres_data:/var/lib/postgresql/data postgres:16Ports privilégiés en rootless
Section intitulée « Ports privilégiés en rootless »En rootless, le processus qui ouvre le port est le vôtre et non root : le noyau applique donc la restriction historique sur les ports inférieurs à 1024.
podman run -p 80:80 nginxSymptôme : permission denied au moment du bind.
Cause : les ports inférieurs à 1024 sont réservés à root par défaut.
# Utiliser un port hautpodman run -p 8080:80 nginx# ou autoriser les ports bassudo sysctl net.ipv4.ip_unprivileged_port_start=80Conteneur arrêté immédiatement
Section intitulée « Conteneur arrêté immédiatement »L'option -d ne rend pas un conteneur persistant, elle détache seulement votre
terminal. La durée de vie du conteneur reste celle de son processus principal.
podman run -d alpineSymptôme : le conteneur passe en Exited (0) aussitôt après le démarrage.
Cause : le processus principal (CMD) se termine instantanément. Un conteneur vit tant que son processus principal tourne.
# Garder actif avec un processus durablepodman run -d alpine sleep infinity# ou lancer un service qui reste actifpodman run -d nginxTravaux pratiques
Section intitulée « Travaux pratiques »Ce lab vous fait manipuler Podman du téléchargement d'image à la consultation de logs. Comptez 20 minutes.
Préparer le terrain
Section intitulée « Préparer le terrain »Le script suivant crée un dossier de travail avec une configuration et des données de test :
# Créer le labmkdir -p ~/podman-lab/data ~/podman-lab/configcd ~/podman-lab
# Créer un fichier de configuration de testcat > config/app.conf << 'EOF'# Configuration de testAPP_NAME=demoAPP_PORT=8080DEBUG=trueEOF
# Créer des données de testecho "Données de test $(date)" > data/test.txt
# Vérifier que Podman fonctionnepodman version
echo "Lab créé dans ~/podman-lab"ls -la ~/podman-labPour tout nettoyer à la fin : podman rm -f $(podman ps -aq --filter "name=test-") 2>/dev/null; rm -rf ~/podman-lab.
Les 6 étapes du lab
Section intitulée « Les 6 étapes du lab »Enchaînez-les dans l'ordre, chacune réutilisant le résultat de la précédente.
Les conteneurs créés portent tous le préfixe test-, ce qui rend possible la
suppression groupée donnée plus haut.
-
Télécharger une image,
podman pull docker.io/library/alpine:3.20. Le préfixedocker.io/library/désigne les images officielles ;:3.20fixe la version. -
Lancer un conteneur simple,
podman run --rm docker.io/library/alpine:3.20 echo "Hello Podman".--rmsupprime le conteneur après exécution ;echoremplace le CMD par défaut. -
Conteneur en arrière-plan,
podman run -d --name test-bg docker.io/library/alpine:3.20 sleep 300.-ddétache le conteneur ;--namele rend facile à référencer. -
Exécuter une commande dans un conteneur,
podman exec test-bg cat /etc/os-release.execlance une commande dans un conteneur déjà en cours d'exécution. -
Shell interactif,
podman exec -it test-bg sh.-igarde stdin ouvert,-talloue un pseudo-terminal. Tapezexitpour sortir. -
Consulter les logs,
podman run -d --name test-nginx docker.io/library/nginx:alpine && podman logs --tail 5 test-nginx.--tail Nlimite aux N dernières lignes.
Exercices progressifs
Section intitulée « Exercices progressifs »Ces exercices vont du lancement d'un conteneur simple à la limitation de ressources. Lisez l'énoncé, cherchez la commande, puis dépliez la solution.
Niveau fondations
Section intitulée « Niveau fondations »Exercice 1, Lancer un conteneur nginx. Lancez un conteneur nginx en arrière-plan, nommé web, accessible sur le port 8080.
Indice : -d pour l'arrière-plan, -p pour le port, --name pour le nom.
Voir la solution
podman run -d --name web -p 8080:80 docker.io/library/nginx:alpine-d détache, -p 8080:80 mappe le port, --name identifie le conteneur. curl localhost:8080 doit ensuite répondre.
Exercice 2, Consulter les logs nginx. Affichez les 10 dernières lignes de logs du conteneur web, avec les timestamps.
Indice : --tail pour limiter, -t pour les timestamps.
Voir la solution
podman logs --tail 10 -t web--tail N limite aux N dernières lignes, -t ajoute la date et l'heure.
Exercice 3, Shell dans le conteneur. Ouvrez un shell interactif dans le conteneur web et vérifiez la version de nginx.
Indice : -it pour le mode interactif, puis nginx -v.
Voir la solution
podman exec -it web sh# Puis dans le shell :nginx -v-it combine interactif et TTY pour obtenir un shell fonctionnel.
Niveau composition
Section intitulée « Niveau composition »Exercice 4, Monter un volume. Lancez un conteneur alpine qui affiche le contenu de ~/podman-lab/data, monté en /data.
Indice : -v source:destination.
Voir la solution
podman run --rm -v ~/podman-lab/data:/data:Z alpine ls -la /data-v monte un dossier de l'hôte ; :Z gère le relabeling SELinux si nécessaire.
Exercice 5, Variables d'environnement. Lancez un conteneur postgres avec POSTGRES_PASSWORD=secret et POSTGRES_DB=demo.
Indice : un -e par variable, ou --env-file.
Voir la solution
podman run -d --name pg -e POSTGRES_PASSWORD=secret -e POSTGRES_DB=demo postgres:16-alpine-e définit une variable ; on peut en enchaîner plusieurs.
Exercice 6, Trouver le port publié d'un conteneur. Récupérez le mapping de ports du conteneur web. En rootless, un conteneur n'a pas d'IP routable : c'est le port publié qui compte.
Indice : podman port, ou --format sur {{.NetworkSettings.Ports}}.
Voir la solution
podman port web# 80/tcp -> 0.0.0.0:8080En rootless, {{.NetworkSettings.IPAddress}} est vide ; podman port donne l'accès réel au service.
Niveau industrialisation
Section intitulée « Niveau industrialisation »Exercice 7, Nettoyage des ressources. Supprimez tous les conteneurs arrêtés et les images non utilisées.
Indice : podman system prune avec les bonnes options.
Voir la solution
podman system prune -a -f-a inclut les images non utilisées, -f exécute sans demander confirmation.
Exercice 8, Conteneur avec limite de ressources. Lancez un conteneur nginx avec au maximum 256 Mo de RAM et 0,5 CPU.
Indice : --memory et --cpus.
Voir la solution
podman run -d --name limited --memory=256m --cpus=0.5 nginx:alpine--memory plafonne la RAM, --cpus limite les cycles CPU. Vérifiez avec podman stats.
Dépannage
Section intitulée « Dépannage »Quand un conteneur se comporte mal, ces méthodes de diagnostic et ces erreurs fréquentes couvrent la grande majorité des cas.
Méthodes de diagnostic
Section intitulée « Méthodes de diagnostic »Suivez cet ordre : l'état du conteneur d'abord, ses logs ensuite, sa configuration en dernier recours. Les trois dernières commandes servent quand le conteneur tourne mais se comporte mal, pas quand il refuse de démarrer.
# Voir tous les conteneurs, y compris arrêtéspodman ps -a
# Consulter les derniers logspodman logs --tail 100 <conteneur>
# Voir toute la configuration d'un conteneurpodman inspect <conteneur> | less
# Lister les processus actifs dans le conteneurpodman top <conteneur>
# Suivre l'utilisation CPU/mémoire en temps réelpodman stats
# Voir les modifications du filesystem par rapport à l'imagepodman diff <conteneur>Erreurs fréquentes
Section intitulée « Erreurs fréquentes »Ces trois erreurs tiennent au contexte d'exécution plutôt qu'à la commande tapée : elles viennent du mode rootless, de la configuration réseau ou des limites de ressources. Aucune ne se corrige en changeant la syntaxe.
| Erreur | Cause probable | Solution |
|---|---|---|
Error: permission denied | Mapping d'UID rootless, SELinux, ou fichiers d'un autre utilisateur | Utiliser --userns=keep-id ou ajouter :Z au volume |
Network is unreachable | Réseau rootless mal configuré, DNS, ou pare-feu | Tester avec --network=host, vérifier /etc/resolv.conf et les règles du pare-feu |
Container was OOMKilled | Limite mémoire dépassée, fuite mémoire, ou limite trop stricte | Augmenter --memory ou optimiser l'application |
Aide-mémoire podman
Section intitulée « Aide-mémoire podman »À garder sous la main : les commandes Podman regroupées par usage, images, création de conteneurs, interaction et diagnostic.
Un nom d'image sans registre est complété par Podman selon registries.conf :
en cas de doute, écrivez le nom complet, par exemple docker.io/library/nginx.
| Syntaxe | Signification | Exemple |
|---|---|---|
podman pull image:tag | Télécharger une image | podman pull nginx:alpine |
podman images | Lister les images locales | podman images |
podman rmi image | Supprimer une image | podman rmi nginx:alpine |
podman search terme | Rechercher sur les registres | podman search --limit 5 nginx |
podman tag source cible | Créer un alias d'image | podman tag nginx:alpine mon-nginx:v1 |
Création de conteneurs
Section intitulée « Création de conteneurs »Les options se placent entre run et le nom de l'image ; tout ce qui suit
l'image est passé au conteneur et non à Podman.
| Syntaxe | Signification | Exemple |
|---|---|---|
podman run image | Créer et démarrer un conteneur | podman run nginx |
-d | Mode détaché (arrière-plan) | podman run -d nginx |
-it | Mode interactif avec TTY | podman run -it alpine sh |
--rm | Supprimer après l'arrêt | podman run --rm alpine echo test |
--name NAME | Nommer le conteneur | podman run --name web nginx |
-p HOST:CONT | Mapper un port | podman run -p 8080:80 nginx |
-v SRC:DEST | Monter un volume | podman run -v ./html:/usr/share/nginx/html nginx |
-e VAR=val | Définir une variable d'environnement | podman run -e MYSQL_ROOT_PASSWORD=secret mysql |
Gestion et interaction
Section intitulée « Gestion et interaction »Partout où un conteneur est attendu, son nom et son identifiant sont interchangeables, et l'identifiant peut être abrégé tant qu'il reste sans ambiguïté.
| Syntaxe | Signification | Exemple |
|---|---|---|
podman ps | Lister les conteneurs actifs | podman ps |
podman ps -a | Lister tous les conteneurs | podman ps -a --filter status=exited |
podman start X | Démarrer un conteneur | podman start web |
podman stop X | Arrêter proprement | podman stop web |
podman rm -f X | Forcer la suppression | podman rm -f web |
podman exec X cmd | Exécuter une commande | podman exec web cat /etc/nginx/nginx.conf |
podman exec -it X sh | Ouvrir un shell interactif | podman exec -it web /bin/bash |
podman logs -f X | Suivre les logs en temps réel | podman logs -f --tail 50 web |
podman cp SRC DEST | Copier des fichiers | podman cp web:/var/log/nginx ./logs |
Diagnostic et nettoyage
Section intitulée « Diagnostic et nettoyage »Toutes ces commandes sont en lecture seule, à l'exception de
podman system prune qui supprime définitivement les ressources inutilisées.
| Syntaxe | Signification | Exemple |
|---|---|---|
podman inspect X | Détails complets en JSON | podman inspect web |
podman top X | Processus du conteneur | podman top web |
podman stats | Ressources en temps réel | podman stats --no-stream |
podman port X | Ports exposés | podman port web |
podman system prune | Nettoyer les ressources inutilisées | podman system prune -f |
podman system df | Espace disque utilisé | podman system df -v |
Checklist de maîtrise
Section intitulée « Checklist de maîtrise »Vous maîtrisez les commandes Podman quand vous pouvez cocher chacun de ces points sans hésiter :
- Je sais lancer un conteneur interactif ou en arrière-plan.
- Je sais exposer des ports et monter des volumes.
- Je sais exécuter des commandes dans un conteneur existant.
- Je sais consulter et suivre les logs en temps réel.
- Je maîtrise le cycle de vie (start, stop, restart, rm).
- Je sais inspecter un conteneur et en extraire des informations.
- Je sais nettoyer les ressources inutilisées.
- Je comprends le mode rootless et ses implications.
Conclusion
Section intitulée « Conclusion »Les commandes podman run, ps, exec, logs et rm constituent le cœur de votre travail quotidien avec les conteneurs. La compatibilité avec Docker facilite la transition, et le mode rootless par défaut renforce la sécurité sans effort supplémentaire.