Repository navigation
Releases
0.20.0
🧪 Virtual machines — experimental / Maszyny wirtualne — eksperymentalne
EN — A new Virtual Machines section (marked Beta) runs full Windows 11 ARM64 and Ubuntu 24.04 in QEMU. This is experimental and a work in progress: it needs QEMU (brew install qemu), and things may change between versions.
- Windows installs itself unattended from your own ISO in about 12 minutes; Ubuntu with a desktop in about 3.
- Live preview with mouse, keyboard, Ctrl+Alt+Del and snapshots; the resolution follows the window.
- Cards with screen thumbnails, per-machine settings, linked clones, delete.
PL — Nowa zakładka Wirtualne maszyny (oznaczona Beta) uruchamia pełny Windows 11 ARM64 i Ubuntu 24.04 w QEMU. Funkcja jest eksperymentalna i wciąż w trakcie prac: wymaga QEMU (brew install qemu), a rzeczy mogą się zmieniać między wersjami.
- Windows instaluje się sam z Twojego ISO w ok. 12 minut, Ubuntu z pulpitem w ok. 3.
- Podgląd na żywo z myszą, klawiaturą, Ctrl+Alt+Del i migawkami; rozdzielczość dopasowuje się do okna.
- Karty z miniaturami ekranu, ustawienia maszyny, klony, usuwanie.
🤖 AI agents via MCP / Agenci AI przez MCP
EN — The app ships an MCP server (cd-mcp): Claude Code and other agents can manage containers, images, volumes and networks, and drive the virtual machines you explicitly allow. Settings → AI Agents → Add to Claude Code.
PL — Aplikacja zawiera serwer MCP (cd-mcp): Claude Code i inni agenci mogą zarządzać kontenerami, obrazami, wolumenami i sieciami oraz sterować maszynami, na które wyraźnie pozwolisz. Ustawienia → Agenci AI → Dodaj do Claude Code.
⚙️ Settings in tabs / Ustawienia w zakładkach
The guest agent for Windows on ARM64 is our own build of the QEMU guest agent (GPL) — source and build script in scripts/qemu-ga-windows-arm64/.
0.11.1
Container Desktop 0.11.1
EN
- Support the project — the Help menu and Settings now link to GitHub Sponsors and Ko-fi. The app is free and will stay that way — no reminders, no pop-ups.
PL
- Wspomóż projekt — w menu Pomoc i w Ustawieniach są linki do GitHub Sponsors i Ko-fi. Program jest darmowy i taki zostanie — bez przypominajek i wyskakujących okien.
0.11.0
Container Desktop 0.11.0
EN
- Shared image store — new cluster option: nodes use the local
containerimage store, so an image built withcontainer buildruns in the cluster right away (container 1.7+). Replaces "Load image into cluster", which container 1.7 removed. - Compatible with container 1.7 — the Kubernetes section was empty on 1.7 because the cluster list changed format; clusters and nodes show again. Worker nodes keep the control plane's CPU and memory.
- CPU usage from the first reading — with container 1.7 the CPU meter shows a value immediately.
PL
- Współdzielony magazyn obrazów — nowa opcja klastra: węzły korzystają z lokalnego magazynu obrazów
container, więc obraz zbudowany przezcontainer buildod razu działa w klastrze (container 1.7+). Zastępuje „Wczytaj obraz do klastra”, które container 1.7 usunął. - Zgodność z container 1.7 — sekcja Kubernetes była pusta, bo lista klastrów zmieniła format; klastry i węzły znów są widoczne. Węzły robocze dostają CPU i pamięć jak control plane.
- Użycie CPU od pierwszego odczytu — z container 1.7 miernik CPU pokazuje wartość od razu.
0.10.0
New
Container snapshots
Snapshots… in a container's menu saves its current state as an image, keeps a history with dates and sizes, and lets you go back to any of them.
- Restoring is undoable. Before replacing the container, the app snapshots its current state. If that fails, nothing is removed.
- Volumes are not included. A snapshot holds the container's filesystem. Data in a mounted volume does not roll back with it.
- A running container can be stopped for the snapshot (on by default). Otherwise a database is caught mid-write.
Needs container 1.6.
Kubernetes clusters with worker nodes
Creating a cluster now offers worker nodes beside the control plane. Each one is its own VM with the same CPU and memory. Needs container 1.6.
Changed
Compose services find each other by name
A service is now reachable by its name from the compose file, so db:5432 works the way compose files expect. Before, only the full container name (project-db) resolved.
Compatible with container 1.6
container 1.6 renamed container k8s to container cluster. On 1.6 the Kubernetes section asked for a newer version even on the newest one. It works again. Cluster nodes, whose label changed with the rename, also stay out of the containers list again, where a control plane could have been deleted.
Nowe
Migawki kontenerów
Migawki… w menu kontenera zapisuje jego bieżący stan jako obraz, prowadzi historię z datą i rozmiarem i pozwala wrócić do dowolnej z nich.
- Przywrócenie da się cofnąć. Przed zastąpieniem kontenera program zapisuje migawkę jego obecnego stanu. Jeśli to się nie uda, nic nie zostaje usunięte.
- Wolumeny nie wchodzą w migawkę. Migawka obejmuje system plików kontenera, a dane w zamontowanym wolumenie się nie cofną.
- Działający kontener może zostać zatrzymany na czas migawki (domyślnie włączone). Inaczej baza danych zostanie zapisana w połowie zapisu.
Wymaga container 1.6.
Klastry Kubernetes z węzłami roboczymi
Przy tworzeniu klastra można teraz dodać węzły robocze obok control plane. Każdy to osobna maszyna wirtualna z tym samym przydziałem CPU i pamięci. Wymaga container 1.6.
Zmienione
Usługi compose widzą się po nazwie
Usługa jest teraz osiągalna pod swoją nazwą z pliku compose, więc db:5432 działa tak, jak zakładają pliki compose. Wcześniej działała tylko pełna nazwa kontenera (projekt-db).
Zgodność z container 1.6
container 1.6 przemianował container k8s na container cluster. Na 1.6 sekcja Kubernetes prosiła o nowszą wersję nawet na najnowszej. Znów działa. Węzły klastra, którym przy okazji zmieniła się etykieta, znów nie pojawiają się na liście kontenerów, skąd dałoby się usunąć control plane.
First launch needs System Settings → Privacy & Security → Open Anyway (ad-hoc signed). Later updates install seamlessly.
Przy pierwszym uruchomieniu: Ustawienia systemowe → Prywatność i ochrona → Otwórz mimo to. Kolejne aktualizacje instalują się bez tego kroku.
0.9.1
Compatible with container 1.5.0
container 1.5.0 removed k8s start. A stopped Kubernetes cluster can no longer
be restarted — it has to be deleted and created again.
The app offered a Start button on every stopped cluster, and on 1.5.0 that
failed with Unknown option '--name' — a message about something else entirely.
It now explains what happened and points at delete. On container 1.4.x the button
still works, because the app checks which CLI you actually have.
Nothing else in 1.5.0 needed a change, and that was checked rather than assumed:
system status keeps its shape, the k8s list table is unchanged, and every
flag the app sends to container run and k8s create still exists.
Text scales with the system again
A dozen or so strings had a fixed point size, so turning text size up in System
Settings did nothing to them. They follow it now.
The smallest badges grew by a point along the way — they had been sitting below
the smallest size macOS offers at all.
Zgodność z container 1.5.0
container 1.5.0 usunął k8s start. Zatrzymanego klastra Kubernetes nie da się
już uruchomić ponownie — trzeba go usunąć i utworzyć na nowo.
Program pokazywał przy każdym zatrzymanym klastrze przycisk Uruchom, a na
1.5.0 kończyło się to błędem Unknown option '--name', czyli komunikatem o
czymś zupełnie innym. Teraz wyjaśnia, co się stało, i wskazuje usuwanie. Na
container 1.4.x przycisk nadal działa — program sprawdza, które CLI faktycznie
masz.
Nic więcej z 1.5.0 nie wymagało zmian, i to zostało sprawdzone, a nie założone:
system status zachowuje kształt, tabela k8s list jest bez zmian, a wszystkie
flagi wysyłane do container run i k8s create nadal istnieją.
Tekst znów skaluje się z systemem
Kilkanaście napisów miało wpisany sztywny rozmiar, więc powiększenie tekstu w
ustawieniach systemowych nic z nimi nie robiło. Teraz reagują.
Najdrobniejsze plakietki urosły przy okazji o punkt — siedziały poniżej
najmniejszego rozmiaru, jaki macOS w ogóle przewiduje.
First launch needs System Settings → Privacy & Security → Open Anyway (the app
is ad-hoc signed, not notarized). Later updates install seamlessly.
Przy pierwszym uruchomieniu: Ustawienia systemowe → Prywatność i ochrona →
Otwórz mimo to. Kolejne aktualizacje instalują się bez tego kroku.
0.9.0
A bin on every container
Deleting was hidden in the context menu while start, stop and terminal sat right
there. It is a button like the others now, in both the card and the table view,
for containers and for compose projects. The confirmation dialog still appears —
that is what makes a mis-aimed click at "stop" harmless.
Containers come back on their own
Picking them one at a time was the awkward part, and the machine already knows
what was running. Container Desktop now keeps that list itself and brings those
containers up after you log in. Stopping a container is how you opt it out.
Picking by hand remains as the other mode, and an upgrade that already has a
selection keeps it — nobody's choices are overwritten.
One limit, stated plainly: the app writes that list. Stop a container with the
app closed, reboot, and it comes back. container has no restart policy and
keeps no record of what was up before the machine went down.
Logs: a bar of their own, and saving to a file
The buttons used to float on top of the log text, so the newest lines — the
reason anyone opens a log — hid behind them. They have a proper bar now, the same
one in container, machine and workload logs.
Saving is new: what you can see, or the whole log, fetched again and
written straight to disk rather than through memory.
Clearer, and more of a piece
Every icon-only button now has a name VoiceOver can read. Before this release
exactly one did — the rest announced themselves as "button", which is not
something anyone would have thought to report.
Toggles look the same throughout (they were checkboxes in one section and
switches everywhere else), the two log viewers stopped calling the same setting
by two names, and cards and dialogs draw from one scale of paddings and corner
radii instead of the fifteen combinations that had accumulated.
Kosz przy każdym kontenerze
Usuwanie było schowane w menu kontekstowym, choć obok stały uruchom, zatrzymaj i
terminal. Teraz to przycisk jak reszta — w obu widokach, dla kontenerów i dla
projektów compose. Potwierdzenie pojawia się jak dotąd, i to ono sprawia, że
chybione kliknięcie w „stop" jest nieszkodliwe.
Kontenery wracają same
Zaznaczanie po jednym było tą niewygodną częścią, a komputer i tak wie, co
działało. Program sam utrzymuje teraz tę listę i podnosi te kontenery po
zalogowaniu. Zatrzymanie kontenera jest sposobem na wypisanie go.
Ręczny wybór został jako drugi tryb, a aktualizacja z istniejącym zaznaczeniem
przy nim zostaje — nikomu nic się nie nadpisze.
Jedno ograniczenie, wprost: to aplikacja pisze tę listę. Zamkniesz program,
zatrzymasz kontener z CLI, zrestartujesz Maca — kontener wróci. container nie
ma polityki restartu ani śladu po stanie sprzed wyłączenia.
Logi: własny pasek i zapis do pliku
Przyciski pływały na tekście logu, więc najnowsze linie — te, dla których się log
otwiera — chowały się za nimi. Mają teraz porządny pasek, ten sam w logach
kontenera, maszyny i obciążeń.
Doszedł zapis: to, co widać, albo cały log, pobierany od nowa i pisany
prosto na dysk, nie przez pamięć.
Czytelniej i spójniej
Każdy przycisk z samą ikoną ma wreszcie nazwę, którą przeczyta VoiceOver. Przed
tym wydaniem miał ją dokładnie jeden — reszta przedstawiała się jako „przycisk",
czego nikt by nie zgłosił.
Przełączniki wyglądają tak samo w całym programie (w jednej sekcji były polami
wyboru, wszędzie indziej suwakami), dwa podglądy logów przestały nazywać to samo
ustawienie dwiema nazwami, a karty i okna dialogowe korzystają z jednej skali
marginesów i zaokrągleń zamiast piętnastu kombinacji, które się uzbierały.
First launch needs System Settings → Privacy & Security → Open Anyway (the app
is ad-hoc signed, not notarized). Later updates install seamlessly.
Przy pierwszym uruchomieniu: Ustawienia systemowe → Prywatność i ochrona →
Otwórz mimo to. Kolejne aktualizacje instalują się bez tego kroku.
0.8.3
Anonymous installation statistics
The app now knows how many people use it — and nothing about who they are.
When Container Desktop checks for updates it sends three values: a random
identifier generated once on this installation, the app version, and the macOS
version. That is enough to answer "how many people, on which version", which the
update feed's own traffic cannot answer — one machine checking daily looks like
thirty machines that checked once.
It does not send your IP address, your computer's name, your account, or
anything about the hardware. Sparkle's own system profile — which reports the Mac
model, the CPU and the memory — stays switched off.
Turn it off in Settings → Privacy → Anonymous statistics. Updates keep
working either way.
The update feed is now served by a Cloudflare Worker that passes the same appcast
through unchanged; the data lives in the EU.
Anonimowe statystyki instalacji
Program wie wreszcie, ile osób go używa — i nic o tym, kim są.
Sprawdzając aktualizacje wysyła trzy wartości: losowy identyfikator wygenerowany
raz na tej instalacji, wersję programu i wersję macOS. Tyle wystarczy, by
odpowiedzieć na pytanie „ilu ludzi i jakiej wersji", na które ruch samego kanału
aktualizacji odpowiedzieć nie potrafi — jeden komputer sprawdzający codziennie
wygląda jak trzydzieści, które sprawdziły raz.
Nie wysyłamy adresu IP, nazwy komputera, konta ani niczego o sprzęcie. Profil
systemu Sparkle'a — raportujący model Maca, procesor i pamięć — pozostaje
wyłączony.
Wyłącznik: Ustawienia → Prywatność → Anonimowe statystyki. Aktualizacje
działają tak czy inaczej.
Kanał aktualizacji serwuje teraz Cloudflare Worker, przepuszczający ten sam
appcast bez zmian; dane leżą w UE.
First launch needs System Settings → Privacy & Security → Open Anyway (the app
is ad-hoc signed, not notarized). Later updates install seamlessly.
Przy pierwszym uruchomieniu: Ustawienia systemowe → Prywatność i ochrona →
Otwórz mimo to. Kolejne aktualizacje instalują się bez tego kroku.
0.8.2 — Kontenery startujące przy logowaniu
PL
Wybrane kontenery wstają przy logowaniu
container nie ma własnej polityki restartu — nie istnieje żadne --restart always — więc silnik sam kontenerów nie podniesie. A skoro usługę uruchamia teraz launchd przy logowaniu, nie ma też aplikacji, która mogłaby to zrobić.
Robi to osobny wpis systemowy: czeka, aż usługa wstanie, i dopiero wtedy uruchamia zaznaczone kontenery.
- Zaznaczasz je w menu kontekstowym kontenera, albo jednym przyciskiem przejmujesz te, które akurat działają
- Lista trzymana jest w osobnym pliku — zmiana zaznaczenia nie rusza samego wpisu systemowego
- Kontenery, których już nie ma, znikają z listy same
- Dostępne tylko przy włączonym uruchamianiu usługi przy logowaniu
✅ Uruchamianie usługi przy logowaniu — potwierdzone
Przełącznik z 0.8.1 działa — usługa zostaje włączona po zamknięciu aplikacji. Dzięki dla osób, które to sprawdziły. To już nie jest rozwiązanie do przetestowania, tylko naprawa.
Autor w „O programie"
Panel był pusty, bo wpis o prawach autorskich był pustym napisem, a pliku z autorstwem nie było wcale. Teraz jest jedno i drugie.
EN
Selected containers come up at login
container has no restart policy of its own — there is no --restart always — so the runtime will not bring containers back. And with launchd now starting the service at login, there is no app around to do it either.
A separate system entry handles it: it waits for the service to come up, then starts the selected containers.
- Tick them in the container's context menu, or take whatever is running with one button
- The list lives in its own file, so changing the selection leaves the system entry untouched
- Containers that no longer exist drop off the list by themselves
- Offered only when starting the service at login is enabled
✅ Starting the service at login — confirmed
The switch from 0.8.1 works — the service stays up after the app quits. Thanks to everyone who checked. It is no longer a fix to try; it is a fix.
The author in About
The panel was empty because the copyright entry was an empty string and there was no credits file. Both are in place now.
Wszystkie teksty w polskim, angielskim i chińskim. / Fully localised in Polish, English and Chinese.
Instalacja / Installation: pobierz ContainerDesktop.dmg. Pierwsze uruchomienie wymaga Ustawienia systemowe → Prywatność i ochrona → Otwórz mimo to. Kolejne aktualizacje instalują się automatycznie.
0.8.1 — Usługa startująca przy logowaniu (do przetestowania)
🧪 Ta wersja zawiera rozwiązanie do przetestowania / This release contains a fix that needs testing
PL
Usługa może startować przy logowaniu
Problem: usługa container uruchomiona z poziomu aplikacji gaśnie po jej zamknięciu. To zachowanie systemu, nie decyzja aplikacji — dzieje się nawet po kill -9, więc nie jest to żadne sprzątanie przy wyjściu.
Rozwiązanie: nowy przełącznik „Uruchamiaj usługę przy logowaniu" w sekcji System.
container system start zapisuje własny plik definicji usługi w ~/Library/Application Support/com.apple.container/apiserver/apiserver.plist. Ten plik już deklaruje RunAtLoad i dopuszcza sesje Aqua oraz Background — tylko że launchd nigdy nie zagląda do Application Support, więc usługa istnieje wyłącznie wtedy, gdy ktoś o nią poprosi.
Przełącznik zakłada dowiązanie do tego pliku w ~/Library/LaunchAgents, gdzie launchd ładuje go przy logowaniu — a wtedy aplikacji nie ma w łańcuchu w ogóle.
- Dowiązanie, nie kopia — aktualizacja
containernie zostawi nieaktualnego duplikatu - Nie rusza Twojego własnego wpisu o tej samej nazwie, jeśli taki masz
- Działa od następnego zalogowania
⚠️ Co jest sprawdzone, a co nie
Sprawdzone: launchd akceptuje to dowiązanie — wyrzuciłem działające zadanie i podniosłem je z powrotem ze ścieżki dowiązania, wstało poprawnie.
Niesprawdzone: czy usługa uruchomiona przy logowaniu faktycznie przeżyje zamknięcie aplikacji. Wymaga to wylogowania, na które nie było okazji. Dlatego to przełącznik do wypróbowania, a nie ogłoszona naprawa.
Jeśli włączysz i po ponownym zalogowaniu usługa działa zanim otworzysz aplikację — i nadal działa po jej zamknięciu — daj znać w zgłoszeniach. To rozstrzygnie sprawę.
Obejście, jeśli wolisz nic nie włączać: uruchom usługę raz z terminala poleceniem container system start — wtedy też przeżywa zamykanie aplikacji.
EN
The service can start at login
The problem: the container service started from inside the app goes down when the app quits. That is the system's behaviour, not the app's choice — it happens on kill -9 too, so it is not cleanup on the way out.
The fix to try: a new "Start the service at login" switch in the System section.
container system start writes its own service definition to ~/Library/Application Support/com.apple.container/apiserver/apiserver.plist. That file already declares RunAtLoad and allows the Aqua and Background session types — but launchd never looks in Application Support, so the service only exists while something has asked for it.
The switch links that file into ~/Library/LaunchAgents, where launchd loads it at login — with the app nowhere in the chain.
- Links, not copies, so a future
containerrelease cannot leave a stale duplicate - Leaves your own entry alone if one already exists under that name
- Takes effect from your next login
⚠️ Verified, and not
Verified: launchd accepts the symlink — the running job was booted out and bootstrapped back from the link path, and came up.
Not verified: whether a login-started service then survives the app quitting. That needs a logout, and there was no opportunity. So this is a switch to try, not an announced fix.
If you turn it on and after logging back in the service is running before you open the app — and still running after you quit it — please say so in issues. That settles it.
Workaround if you would rather not enable anything: start the service once from a terminal with container system start and it survives the app quitting too.
Wszystkie teksty w polskim, angielskim i chińskim. / Fully localised in Polish, English and Chinese.
Instalacja / Installation: pobierz ContainerDesktop.dmg. Pierwsze uruchomienie wymaga Ustawienia systemowe → Prywatność i ochrona → Otwórz mimo to. Kolejne aktualizacje instalują się automatycznie.
0.8.0 — Własny CNI dla klastra i czytelniejsze ikony
PL
Własna wtyczka sieciowa dla klastra
Przy tworzeniu klastra Kubernetes można teraz wskazać manifest CNI — na przykład Cilium — zastosowany zaraz po jego starcie. Pole jest w sekcji Zaawansowane, obok obrazu węzła, z przyciskiem wyboru pliku. Puste = sieć domyślna.
container k8s create obsługiwał --cni od dawna; brakowało tego tylko w aplikacji. Dzięki @musionx za pytanie w #31, przy okazji którego to wyszło.
Czytelniejsze ikony na pasku bocznym
Symbole w kolorowych kafelkach są mniejsze i mają margines, więc kafelki czytają się jak ikony, a nie jak pełne bloki koloru.
⚠️ Znany problem
Uruchomienie usługi container z poziomu aplikacji wiąże ją z aplikacją — po zamknięciu programu usługa gaśnie.
Obejście: uruchom usługę raz z terminala i przeżyje zamykanie aplikacji:
container system start
Problem jest odtwarzalny i intensywnie badany, ale nie znaleziono jeszcze przyczyny. Atrapa aplikacji GUI nigdy go nie odtwarza, nasza zawsze. Wykluczono eksperymentalnie: sposób uruchomienia procesu, własną sesję procesu, typ aplikacji, flagi polecenia, cykliczne odpytywanie, uprawnienie get-task-allow, element w pasku menu, identyfikator pakietu, Sparkle oraz — dwukrotnie — przekazanie startu do launchd. To nie jest też kwestia SDK 27.
Dwie poprawki napisano, przetestowano, uznano za nieskuteczne i wycofano zamiast wypuścić.
EN
Your own network plugin for a cluster
When creating a Kubernetes cluster you can now point at a CNI manifest — Cilium, for example — applied as soon as the cluster is up. The field sits in Advanced, beside the node image, with a file picker. Empty means the default network.
container k8s create has accepted --cni all along; only the app was missing it. Thanks to @musionx for the question in #31 that surfaced it.
Clearer sidebar icons
The glyphs in the coloured tiles are smaller and have room around them, so the tiles read as icons rather than as solid blocks of colour.
⚠️ Known issue
Starting the container service from inside the app binds it to the app — quitting takes the service down with it.
Workaround: start it once from a terminal and it survives:
container system start
It reproduces reliably and was chased hard, but the cause has not been found. A dummy GUI app never reproduces it; this one always does. Eliminated by experiment: the spawn method, a detached session, the activation policy, command flags, three-second polling, the get-task-allow entitlement, a menu bar status item, the bundle identifier, Sparkle, and — twice — handing the start to launchd. It is not the SDK 27 build either.
Two candidate fixes were written, tested, found not to work, and reverted rather than shipped.
Wszystkie teksty w polskim, angielskim i chińskim. / Fully localised in Polish, English and Chinese.
Instalacja / Installation: pobierz ContainerDesktop.dmg. Pierwsze uruchomienie wymaga Ustawienia systemowe → Prywatność i ochrona → Otwórz mimo to. Kolejne aktualizacje instalują się automatycznie.