A native macOS workspace for Apple’s container runtime.
Browse, run, build, inspect and clean up Linux containers on your Mac with live resource gauges, a built-in terminal and an optional local AI playground, while Apple’s container CLI stays the runtime authority.
Features · Screenshots · Getting started · Safety & privacy · Downloads
- One native window for the whole runtime. Containers, images, volumes, networks, registries, machines, builds, Compose, Kubernetes, system services and cleanup, in searchable SwiftUI tables with inline details.
- Live, at a glance. Every container shows CPU and memory against its configured limits. Gauges turn amber at 70% and red at 90%.
- The CLI stays in charge. Manage your existing Apple container runtime with action previews and a record in Activity.
- Safe by default. Destructive actions are confirmed and scoped, secrets are redacted from previews and output, and Cleanup never runs bulk prune commands.
- Local AI built in. Discover MLX models, serve one on
127.0.0.1, and chat with it. Conversations stay in memory on your Mac.
Local AI: run an app-owned MLX-LM server on loopback and chat with it. Prompts and replies stay in memory and never reach Activity or preferences.
- Browse containers, images, volumes, networks, registries and machines in searchable native tables with inline resource details. Containers show live CPU and memory usage against configured capacity.
- Run containers in the background, stream logs, inspect redacted metadata, open an interactive terminal, monitor stats, and copy or export files.
- Open Logs in the Runtime sidebar to merge container streams with stable source colours, source and text filters, arrival timestamps, pause/resume, and Jump to Latest. Shift-click lines to select a range, or set a time range, then export the filtered selection. Pause keeps collecting in a bounded in-memory buffer (20,000 lines / 4 MB of UTF-8 text); the initial tail includes up to 200 lines per source. Streams stop when you leave Logs.
- In a container’s Stats tab, choose 15 minutes or 60 minutes for CPU/RAM sparklines with restart, exit and limit-change markers. Hover over either chart to inspect the timestamp, CPU/RAM values and nearby events with a shared cursor; gaps show “No sample at this time.” Session history collects while a window is visible, including when another app has focus, across all sections. Events reflect successful inventory reads and app actions; short external transitions between polls may be missed.
- Enable unexpected-exit or CPU/RAM threshold notifications in Settings → Container Monitoring. Thresholds are percentages of configured limits and re-arm after usage falls 5 percentage points below the threshold. Notifications require macOS permission and are off by default.
- Use Edit Limits… on a container to review new CPU and memory limits and recreate it with downtime. The flow backs up the stopped writable disk and boot files, keeps the full launch settings and existing mounts, and restores the prior running/stopped state. A container that has never started can change limits without booting. It attempts restoration if recreation fails. This flow requires the default CLI and API server at exactly 1.5.0 and rejects configurations it cannot preserve safely before stopping them. See Safety and data handling for how recreation and recovery work.
- Pull, push, tag, save and load OCI images.
- Create and name a stack, including an empty stack to populate later.
- Add existing containers, run new containers into a stack, move members between saved stacks, or remove members.
- Rename or delete a saved stack. Removing members or deleting a stack preserves the containers and their data.
- Discover groups from project labels and shared names, then save a discovered group as an editable stack.
- View aggregate metrics, related resources, and tagged merged logs; start, stop, or restart saved and label-verified stacks.
Saved membership is local to ContainerDesk and separated by the configured CLI runtime. It takes priority over discovery; explicitly removed members remain ungrouped. Membership changes do not alter container networking, storage, or runtime labels. Stack definitions persist in ~/Library/Application Support/ContainerDesk/stacks.json.
- Use Containers → Profiles to save, edit, duplicate, import and export reusable environment profiles. Profiles retain the image, optional command and container name, ports, mounts, networks, CPU/memory limits, platform, environment-file paths and required variable names. Review & Run… opens the full launch form before starting anything. You can also save the current Run form as a profile or load an existing profile there.
- Environment override values entered in Run are transient: saving remembers their names as required variables, not their values. Supply them again when running, or reference an existing UTF-8 environment file using an absolute path or
~/. Files are read once at launch (up to 1 MiB each); their values are passed transiently and redacted from command previews/output. Explicit overrides take precedence. Quoting and$in environment files remain literal, matching the CLI; a bare variable name inherits a value from the app’s environment when available. - Duplicating a profile clears its container name and opens an editor. Change the ports and volume sources for a separate environment: existing named volumes reuse their data, while new volume names create empty volumes during launch. A profile does not clone a container or its files. Exported JSON includes commands and local path references, so review those before sharing and edit paths after importing on another Mac.
- Build images with BuildKit and inspect builder controls.
- Create local Compose projects and manage them with the installed plugin’s
upanddowncommands. If a saved Compose or Kubernetes library cannot be read, Library Recovery… lets you retry, export the damaged data, import repaired JSON or reset after saving a private backup. Recovery changes remembered references only. - Create, list, load images into, configure and delete local Kubernetes clusters with the installed experimental plugin.
- Manage runtime service state, logs, disk use, DNS domains, kernel selection and read-only system properties. DNS administration uses macOS’s administrator prompt for only the validated DNS command.
- Use Cleanup for a manual scan of unused containers, images, networks and volumes. Eligible stopped containers, unused images and unused networks are selected by default; volumes stay unselected because they contain stored data. Plugin-owned containers are left to their plugin’s dedicated teardown workflow. Review the exact candidates before removal; each selected resource is revalidated and removed individually. Cleanup does not run bulk prune commands.
- Activity records the operations you start from every screen, with command previews, timing, state and exit codes. Command output itself is not saved.
- In Local AI → MLX Models, discover Hugging Face cache snapshots, import an existing model folder, or explicitly download a public
owner/modelfrom Hugging Face into ContainerDesk’s managed models folder. ContainerDesk displays the detected version and enables MLX features only when the selectedmlx_lmexecutable reports supported version 0.32.2 and exposes the required server options. - Use the Running Services view to discover verified MLX/Jev endpoints already listening on this Mac. It shows model names and loopback endpoints as external, read-only services; ContainerDesk cannot stop them or infer where their model files are stored.
- Start and stop an app-owned MLX inference server explicitly, with one active server per model. It binds only to
127.0.0.1; use its copied OpenAI-compatible/v1endpoint from local clients. The Chat Playground streams replies from that owned server, with per-window in-memory conversations, ⌘ Return to send, Stop Generation, Clear, and Copy Reply.
- Apple silicon Mac running macOS 26 or later.
- Apple
containerCLI 1.5.0 or compatible release, plus its local system service. - Optional local MLX support requires Apple silicon and an existing Python environment with MLX-LM 0.32.2 and Hugging Face Hub installed. The app verifies this exact MLX-LM version and the required local server options; other versions are not currently supported. Install Python and MLX-LM separately; model downloads are always an explicit action in the app. See MLX setup under Safety and data handling.
-
Install Apple’s
containerCLI (from its releases page or Homebrew) and start its system service:container system start
-
Clone, build and launch ContainerDesk. Building from source requires Swift 6.2 or newer:
git clone https://github.com/MacHatter1/ContainerDesk.git cd ContainerDesk CONTAINERDESK_BUILD_CONFIGURATION=release ./script/build_and_run.sh
The script builds dist/ContainerDesk.app and opens it. You can then move the app to Applications.
The app discovers the Homebrew CLI from standard install paths and inherited PATH. If it cannot find the executable, open ContainerDesk → Settings and select it.
The build script signs the app ad hoc and verifies the signature strictly. Ad hoc signing protects bundle integrity but does not provide Developer ID trust or Apple notarization. Quarantined downloads can still be blocked by Gatekeeper; this project does not claim a tested notarized download flow. If you download a build, macOS may warn or block the first launch. If you trust the source and have verified the download, try opening the app once, then use System Settings → Privacy & Security → Open Anyway if macOS offers that option. Managed Macs may restrict this override. See Apple’s instructions for opening an unidentified or unnotarized app.
Quitting the app
Quitting ContainerDesk leaves Apple container services and workloads running. During limits replacement or recovery, Quit shows progress and offers Keep App Open. If recovery has not finished after 30 seconds, the app stays open and explains why; it does not interrupt the disk transaction. Once recovery finishes, Quit stops app-owned commands, log followers, terminal sessions, MLX servers and downloads before exiting. Service start and stop are available explicitly from System.
Activity and command output
Activity records command previews, timing, status and exit codes. Command output is temporary and is not saved in Activity. Output is bounded in memory; if a command produces more than the app can handle, it reports an error and cancels that command. Retry is available only for supported read-only commands; changes must be reviewed again through their original screen.
Edit Limits: recreation and recovery
Limits recreation requires copy-on-write cloning between the container disk and recovery directory, normally on the same APFS volume. It retains private recovery files in ~/Library/Application Support/ContainerDesk/LimitsRecovery. These contain the original disk and configuration, including environment values, and may remain boot dependencies of the recreated container. Do not remove them while that container exists.
Mounted volume and bind data stays in its original location; the recovery copy does not snapshot those external files. The guest TTY setting is preserved. Process memory, attached terminal sessions, open connections, runtime log history, and automatically assigned network addresses do not survive recreation. Quit waits up to 30 seconds for replacement or recovery, with visible progress, then stays open if the transaction is still active. Conflicting runtime actions are blocked while replacement is active. If the app is force-quit or interrupted, retain the recovery directory and inspect the container before attempting another change; recovery after interruption is manual.
Use Settings → Review Limits Recovery Files… to inspect completed rollback copies and their allocated disk size. Removal requires explicit selection and confirmation, a complete inventory of all containers (including stopped containers), and no references to the session's files. Active limits changes block removal. Sessions with missing, unknown, interrupted or manual-recovery outcomes are retained; this includes sessions created before outcome tracking was added. APFS clone sharing means the space actually reclaimed can differ from the displayed allocation.
MLX setup
MLX setup is explicit: install Python, Apple’s MLX-LM 0.32.2, and Hugging Face Hub in the same Python environment. Ensure its mlx_lm executable is available on PATH, or select that executable in Settings; keep the environment’s Python interpreter available for model downloads. If selecting mlx_lm.server, its sibling mlx_lm executable must be in the same folder; the app uses that sibling for verification and commands, so a standalone server entrypoint is insufficient.
The app does not install dependencies or broaden support to unverified MLX-LM versions. Model downloads are user initiated; cached/imported files are never deleted by ContainerDesk. Forget removes only an imported-folder reference; Move to Trash is offered only for verified ContainerDesk-managed downloads.
Chat privacy
Chat prompts, transcripts, generated replies, download output, and server logs are transient and are not written to Activity or preferences. Conversations are kept separately per window and server session, bounded in memory, and a generation is cancelled when its Chat view closes, the server stops, or the app quits. Closing a window clears its chat state; switching views preserves that window’s conversation. Starting a new server session starts a new conversation.
Download DMG or ZIP packages from GitHub Releases, along with the matching SHA-256 checksum. They are not Developer ID signed or notarized; see macOS Gatekeeper before opening a downloaded build.
Keep the download and its .sha256 file in the same folder, then verify the checksum.
For example, using the version and format you downloaded:
shasum -a 256 -c ContainerDesk-v1.0.0-macos-arm64.dmg.sha256Build, test and benchmark instructions are in the development guide. See the capability reference for supported commands and limitations.
ContainerDesk is released under the MIT License. It is provided as is, without warranty of any kind.
Screenshots show the real app with a demo storefront stack on Apple container 1.5.0 and a Llama 3.2 3B model served locally by MLX-LM 0.32.2. ContainerDesk is an independent project and is not affiliated with or endorsed by Apple.



