Apple Container : lancer des conteneurs Linux sur Mac, sans Docker Desktop
Apple Container (containerization) : l'outil natif d'Apple, stable en 1.0 depuis juin 2026, pour créer et exécuter des conteneurs Linux sur macOS 26. Install, build, réseau, volumes, limites — guide pratique.
Table des matières

% container run -d --name serveur-web nginx% container lsID IMAGE STATE IPa3f1c2... nginx:latest running 192.168.64.3% open http://192.168.64.3Une ligne pour lancer, une autre pour lister, et on atteint le service directement sur son IP. Pas de daemon Docker permanent, pas d’icône dans la barre des menus, pas de licence à débattre. Depuis 2025, Apple propose container, un outil open source écrit en Swift pour exécuter des conteneurs Linux nativement sur Mac Apple Silicon. La version 1.0 stable est sortie le 9 juin 2026 (la 1.1.0 est déjà là) : la CLI et les API XPC sont désormais figées, avec garantie de compatibilité entre versions correctives.
Cet article est un démarrage pratique complet : installation, build, run, réseau, volumes, ressources, et les limites regardées en face. Si la conteneurisation vous est nouvelle, les notions d’image, de couche et de registre sont les mêmes qu’avec Docker — ce qui suit est directement lisible.
1. Comprendre container et son architecture
container est un outil CLI édité par Apple, open source sur GitHub, sous licence Apache 2.0, gratuit. Il consomme et produit des images compatibles OCI : on pull depuis n’importe quel registry standard (Docker Hub, GitHub Container Registry, registry privé), et on pousse des images que n’importe quel runtime OCI peut rejouer ailleurs (Kubernetes, Docker, Firecracker…).
La stack technique :
- Swift + le framework Virtualization de macOS pour l’isolation.
- Le paquet Swift
Containerizationpour les API bas niveau (images, réseau, démarrage des VM). vminitd, un mini système d’init lui aussi en Swift, qui démarre les conteneurs en une fraction de seconde.
Architecture : une VM par conteneur
C’est la différence fondamentale avec Docker Desktop. Là où Docker fait tourner tous les conteneurs dans une seule VM Linux partagée (un noyau commun), container lance chaque conteneur dans sa propre machine virtuelle légère, via le framework Virtualization de macOS.
Trois conséquences concrètes :
- Un noyau par conteneur : en théorie, des conteneurs peuvent s’appuyer sur des noyaux différents. L’isolation est plus forte qu’un runtime partagé — un conteneur compromis ne partage pas son noyau avec ses voisins.
- Une IP par conteneur, exposée sur le réseau de l’hôte macOS (et non enfermée dans un réseau interne de VM comme sous Docker Desktop). On y revient dans la section réseau.
- Ressources à la demande : CPU et mémoire sont alloués quand un conteneur est actif, libérés ensuite. Pas de VM qui tourne en permanence en arrière-plan.
container ou Docker Desktop : quelles différences ?
| Critère | container (Apple) | Docker Desktop |
|---|---|---|
| Éditeur | Apple | Docker, Inc. |
| Licence | Open source (Apache 2.0) | Propriétaire (gratuit sous conditions, payant en entreprise) |
| Architecture | Une micro-VM par conteneur | Une VM Linux partagée |
| Noyau Linux | Un noyau dédié par conteneur | Noyau partagé |
| Réseau | Une IP par conteneur (pile macOS) | NAT / bridge via la VM |
| Plateforme | Apple Silicon + macOS 26 uniquement | Intel et Apple Silicon ; macOS, Windows, Linux |
| Daemon | Pas de daemon permanent | Daemon + icône barre des menus |
| Docker Compose | Pas natif (projets tiers) | Intégré |
| Démarrage | Sous la seconde, ressources à la demande | VM active en permanence |
| Maturité | Stable depuis la 1.0 (juin 2026) | Mature, écosystème très large |
container n’est donc pas (encore) un remplaçant universel de Docker Desktop. C’est un runtime natif, léger, sans licence, taillé pour Apple Silicon — avec un périmètre plus étroit.
2. Installer container sur macOS
Deux conditions :
- Mac avec Apple Silicon. Pas de support Intel ; les mainteneurs ne traitent pas les issues non reproductibles sur Apple silicon.
- macOS 26 (Tahoe). L’outil exploite les nouvelles APIs de virtualisation et réseau de cette version.
Ces deux points excluent les Mac Intel et les macOS antérieurs — c’est la principale barrière à l’adoption. Sur ce créneau précis, c’est en revanche une option crédible.
Installation
Deux méthodes.
Méthode officielle : téléchargez le paquet .pkg signé et notarisé depuis la page des releases. Préférez le paquet signé — il évite de contourner Gatekeeper. Double-clic, mot de passe admin. L’installeur place sous /usr/local/bin : container, container-apiserver, update-container.sh, uninstall-container.sh.
Homebrew (pratique si vous gérez vos outils CLI ainsi) :
brew install containerDémarrer le service et installer le noyau
Une fois installé, on lance le service système qui gère le cycle de vie des conteneurs :
container system startAu premier lancement, si aucun noyau Linux n’est présent, l’outil propose d’en installer un — issu de Kata Containers :
% container system startVerifying apiserver is running...Installing base container filesystem...No default kernel configured.Install the recommended default kernel fromhttps://github.com/kata-containers/kata-containers/releases/download/3.17.0/kata-static-3.17.0-arm64.tar.xz? [Y/n]: yInstalling kernel...On valide, le service démarre. Pour vérifier que tout est en place :
container system version # versions container + apiservercontainer ls -a # liste (vide au premier run)Note migration : depuis la 1.0, la configuration système passe par un fichier TOML (~/.config/container/config.toml). Les sous-commandes container system property get/set des versions 0.x ont été retirées — à savoir si vous migrez.
Mises à jour et retours arrière via les scripts /usr/local/bin :
container system stop/usr/local/bin/update-container.sh # montée de version/usr/local/bin/uninstall-container.sh -k # -k garde les données, -d les supprimecontainer system start3. Lancer et piloter vos conteneurs
La syntaxe est volontairement proche de Docker — quasi pas de réapprentissage. Le panneau de commandes :
CONTAINER SUBCOMMANDS: create, run, start, stop, kill, list (ls), delete (rm), exec, inspect, logs, statsIMAGE SUBCOMMANDS: build, image (i), registry (r)SYSTEM SUBCOMMANDS: system (s), builder, volume, machineAbréviations partout : container ls -a pour container list --all. Lancer un shell interactif, ou un conteneur en arrière-plan :
container run -it alpine sh # shell interactifcontainer run -d --name serveur-web nginx # détaché, nomméSuivre les ressources en temps réel — l’équivalent de docker stats :
container statsCONTAINER ID CPU % MEMORY USAGE NET RX/TX PIDSserveur-web 0.00% 22.29 MiB / 1.0 GiB 31.49 KiB / 0.59 K 6Arrêter, inspecter, entrer dans un conteneur :
container stop serveur-webcontainer inspect serveur-web # détails complets (JSON), dont un bloc resourcescontainer exec serveur-web shTravailler avec les images
Pull depuis un registry, avec tag ou architecture explicite :
container image pull alpinecontainer image pull nginx:1.27-alpinecontainer image pull --platform linux/amd64 nginx:latest # forcer amd64 sur Apple Siliconcontainer image pull ghcr.io/<org>/<image>:<tag> # GitHub Container RegistryLister et inspecter :
container image lsNAME TAG DIGESTalpine latest 28bd5fe8b56dnginx latest ec4ed8b5299e
container image inspect nginx:latest # métadonnées détaillées (JSON)Sur Apple Silicon, c’est la variante arm64 qui est récupérée par défaut.
Limite à connaître : il n’existe pas d’équivalent à docker search. Aucune commande pour interroger Docker Hub depuis le terminal. Pour trouver une image, passez par hub.docker.com ou un client graphique.
4. Construire et publier une image OCI
On build une image personnalisée : une page statique servie par Nginx.
mkdir mon-app && cd mon-appFROM nginx:alpineLABEL org.opencontainers.image.title="mon-app" \ org.opencontainers.image.description="Démo servie par Nginx"COPY index.html /usr/share/nginx/html/index.htmlEXPOSE 80Un index.html minimal à côté, puis le build :
container build -t mon-app .Le piège Rosetta 2
À ce build, vous pouvez tomber sur cette erreur :
Error: internalError: "failed to bootstrap container"(cause: ... "Rosetta is not installed" ...)Le builder BuildKit s’appuie sur Rosetta 2 (la couche de traduction x86→ARM d’Apple). Si elle n’est pas installée, une commande suffit :
softwareupdate --install-rosetta --agree-to-licensecontainer build -t mon-app . # relance → succèsBuild multi-architecture et push
container sait produire des images multi-arch (ARM64 + AMD64), pratique pour publier une image consommable partout :
container build --arch amd64,arm64 -t mon-app:1.0.0 .Publication sur un registry — privilégiez un jeton d’accès personnel (PAT) plutôt qu’un mot de passe, avec date d’expiration :
container registry login --username <user> docker.iocontainer image tag mon-app:latest docker.io/<user>/mon-app:1.0.0container image push docker.io/<user>/mon-app:1.0.0container registry list # registres où des identifiants sont enregistrésL’image construite ici tourne ensuite sur n’importe quel runtime OCI. C’est le vrai gain par rapport à un runtime fermé : pas de format propriétaire, pas de lock-in.
5. Réseau : exposer et nommer un conteneur
C’est ici que le modèle se démarque vraiment. Sous Docker Desktop, les adresses IP des conteneurs vivent dans un réseau interne à la VM et ne sont pas joignables depuis macOS : on publie un port (-p 8080:80) pour atteindre le service via localhost. Avec container, chaque conteneur reçoit une IP exposée sur le réseau de l’hôte macOS, directement joignable, sans publication de port :
container ls # serveur-web running 192.168.64.3open http://192.168.64.3Joindre un conteneur par son nom
On peut aussi résoudre un conteneur par <nom>.<domaine> plutôt que par son IP. Mais ça demande deux étapes complémentaires qui ne font pas la même chose :
-
Enregistrer le domaine auprès de macOS (nécessite
sudo) — c’est lui qui rend le domaine résolvable depuis l’hôte :Terminal window sudo container system dns create mac -
Désigner ce domaine comme défaut dans
~/.config/container/config.toml— ce fichier utilisateur ne fait que choisir le domaine à appliquer ; il ne peut pas faire l’enregistrement système :[dns]domain = "mac"
Les deux sont requis. Déclarer un domaine dans config.toml sans l’avoir créé à l’étape 1 pointe vers un domaine que macOS ne sait pas router. Le service ne relit ce fichier qu’au démarrage :
container system stop && container system startcontainer system dns list # DOMAIN: macDès lors, serveur-web.mac se résout depuis le Mac.
6. Persister les données (volumes, bind mounts)
Par défaut, tout ce qu’un conteneur écrit disparaît avec lui. Pour conserver un état, deux mécanismes — comme Docker.
Bind mount (idéalement en dev : éditer le code côté Mac, l’exécuter dans le conteneur) :
container run -it -v $(pwd):/app -w /app alpine shcontainer run -it -v $(pwd)/data:/data,readonly alpine sh # lecture seuleVolume nommé (état applicatif géré par container, indépendant de l’arborescence hôte — recommandé pour une base) :
container volume create donnees-bddcontainer run -d --name bdd \ -e POSTGRES_PASSWORD=secret \ -v donnees-bdd:/var/lib/postgresql/data \ postgres:16
container volume lscontainer volume inspect donnees-bddcontainer volume prune # supprime les volumes non utilisésUn volume utilisé par un conteneur, même arrêté, ne peut pas être supprimé : retirez d’abord le conteneur qui le référence.
| Critère | Bind mount -v /chemin:/cible | Volume nommé -v nom:/cible |
|---|---|---|
| Emplacement | Un dossier précis du Mac | Géré par container |
| Cas type | Dev : éditer le code côté Mac | Données applicatives (BDD, journaux) |
| Accès Finder | Oui | Non, via le conteneur |
| Portabilité | Dépend de l’arborescence hôte | Indépendant du poste |
En pratique : bind mount pour le code que vous éditez, volume nommé pour l’état que l’application produit.
7. Dimensionner CPU et mémoire
Par défaut, un conteneur reçoit 4 CPU et 1 Go de RAM. Pour ajuster :
container run -d --name web --cpus 2 --memory 2g nginx--cpus <n>: cœurs alloués à la VM du conteneur.--memory <taille>: suffixesk/m/g/t, unités binaires (2g= 2 Gio) ; sans suffixe, en octets.
Vérifiable via container inspect (bloc resources). Cas particulier du builder : la VM BuildKit a ses propres valeurs par défaut, plus modestes (2 CPU, 2 Gio). Pour un build lourd, démarrez-la explicitement :
container builder start --cpus 8 --memory 8gPlutôt que de répéter --cpus/--memory à chaque run, on peut définir des valeurs par défaut persistantes dans ~/.config/container/config.toml :
[container]cpus = 2memory = "2g"8. Aller plus loin : machine, Compose, GUI
container machine : un Linux persistant façon WSL
La 1.0 introduit aussi le mode container machine, qui fournit un environnement Linux persistant sur le Mac. Là où un conteneur est calqué sur une application éphémère, une container machine est calquée sur un système Linux complet : votre dossier personnel macOS y est monté, vous éditez côté Mac et compilez côté Linux, et vous pouvez y faire tourner des services au long cours. C’est l’équivalent le plus proche de WSL côté macOS. C’est un sujet à part entière, qui mérite son propre article.
Écosystème : Compose et interfaces graphiques
Docker Compose n’est pas supporté nativement. Décrire une stack multi-services dans un docker-compose.yml et la lancer d’une commande n’est pas (encore) possible avec container seul. La communauté commence à combler ce vide — par exemple Container-Compose (de Mcrich23, en Swift), qui lit un fichier au format Compose et le traduit en commandes container. Pratique mais encore immature.
Côté interfaces graphiques (Apple ne fournit rien d’officiel), quelques clients open source s’appuient sur la CLI ou les API :
- Orchard : app macOS native en Swift, via XPC. Création/démarrage/arrêt de conteneurs, pull et recherche d’images, logs parallèles, monitoring CPU/mémoire/réseau.
- iContainer : app SwiftUI (MIT), tableau de bord, shell interactif persistant, stats graphées, gestion des images et registres.
9. Verdict : container ou Docker Desktop ?
Limites honnêtes
- Apple Silicon + macOS 26 uniquement. C’est l’API de virtualisation qui dicte. Flotte Intel ou macOS antérieur → Docker Desktop ou Colima.
- Pas de Docker Compose natif. Pour une stack
web + db + cache, l’ergonomie Compose reste imbattable ; on se rabat sur des projets tiers immatures. - Pas de runtime partagé. Le modèle micro-VM implique un noyau par conteneur. Sur de la densité forte, la RAM grimpe plus vite qu’avec Docker. À benchmarker au-delà de quelques conteneurs.
- Pas de
docker search. Recherche d’images via le site Docker Hub ou un client graphique. - Écosystème jeune. Moins d’intégrations, moins de recettes que Docker installé depuis quinze ans.
À retenir
container apporte une chose que Docker Desktop n’a jamais offerte : un runtime OCI natif, signé, open source, sans licence — sous la condition stricte d’Apple Silicon + macOS 26. Le modèle « une VM par conteneur » donne une isolation forte par défaut et des ressources à la demande, au prix d’une densité plus gourmande. La portabilité OCI est réelle : ce que vous buildez ici tourne ailleurs. Avec la 1.0 stable (juin 2026) et la fonctionnalité container machine, l’outil devient crédible pour du dev quotidien sur un Mac récent. Pour une flotte mixte, du Compose ou de la densité, Docker Desktop reste.
Sources : dépôt apple/container, paquet apple/containerization, session WWDC25 « Meet Containerization », article IT-Connect de référence.