Files
apple-container-nova/README.md
T
thatguygriffandClaude Opus 5 0506f44db3 Build the Apple Container extension
Turns the empty scaffold into a working Nova extension for Apple Container
and container-compose, in the shape of the Docker Suite extension.

Sidebar (Scripts/Sidebar):
- System, Containers, Images, Volumes and Networks sections
- Containers grouped into compose projects via the com.docker.compose.project
  label container-compose stamps; project rows drive compose up/down/build
  against the matching workspace file
- Lifecycle, shell, logs, inspect, browse and copy commands per resource
- Apple Container publishes no event stream, so the sidebar polls while
  visible and only reloads a section when a fingerprint of its data changes,
  which keeps selection and expansion intact

Hostnames (Scripts/Hostnames.js):
- A container's hostname is <name>.<domain> and the domain lives in Apple
  Container's config.toml, which has no CLI setter, so the Hostname Domain
  preference reads and writes that file directly
- Changing it offers to register the domain with macOS and restart the
  services; the write preserves the file's other tables and its mode

Language support:
- Dockerfile and Compose syntaxes backed by tree-sitter grammars built by
  Tools/build-syntaxes.sh, pinned to revisions that generate ABI 14
- The Compose syntax is named dockercompose because that is the languageId
  docker-language-server recognises compose files by
- docker-language-server is downloaded on first use rather than bundled, at
  roughly 40 MB

Icons are generated by Tools/make-icons.py so they can be regenerated rather
than hand-maintained.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UnSBcR5Lywz5Fbj5FmVbfc
2026-08-18 22:45:14 -03:00

8.3 KiB

Apple Container for Nova

Manage Apple Container and container-compose from Nova: a sidebar for the things you run, commands for the things you do, and language support for the files you write.

Built for people whose local development runs on container rather than Docker, and modelled on the shape of Jonathan Coole's Docker Suite for Nova.

Requirements

  • macOS with Apple Container installed (container on your PATH, or point at it in the extension's preferences)
  • container-compose for the compose commands — optional, everything else works without it
  • Nova 11 or later

The sidebar

System — the container services and the builder, with their state, plus disk usage, the hostname domain and the DNS domains macOS resolves. Start, stop and restart the services from here; when they are not running, the rest of the sidebar stays out of your way until they are.

Containers — grouped into compose projects using the com.docker.compose.project label that container-compose stamps on the containers it creates. Containers created any other way collect in an ungrouped bucket. Start, stop, restart, kill and delete them; open a shell or follow the logs in your terminal; read logs or inspect output in a Nova tab; open a published port in your browser; copy a name, address or URL. Containers publishing more than one port ask which to open, and the list includes the container's DNS name and IP as well.

Select a compose project to run container-compose up, down or build against the compose file it came from, or to open that file.

Images — grouped by repository, with sizes and ages. Run, pull, push, tag, inspect and delete, plus prune for the whole section. Apple Container's own builder and init images are hidden unless you ask for them.

Volumes — inspect, reveal the backing disk image in Finder, create, delete and prune.

Networks — subnets and gateways, create, inspect, delete and prune. The built-in default network is protected from deletion.

Apple Container publishes no event stream, so the sidebar polls while it is visible. The interval is configurable, and a section only reloads when something actually changed, so your selection survives.

Hostnames and DNS

Apple Container gives a container the hostname <name>.<domain>, where the domain comes from its own config.toml, and macOS only resolves that domain once a resolver entry exists for it. Those are two separate steps, and the extension treats them as one.

Set Hostname Domain in the extension's preferences. Changing it writes the domain to ~/Library/Application Support/com.apple.container/config/config.toml, offers to register it with macOS through sudo container system dns create in your terminal if it is not registered already, and offers to restart the services so the change takes hold. After that, mysql.test resolves from your Mac and from other containers. Clearing the field goes back to unqualified hostnames.

The setting starts out showing whatever config.toml already says, so it reflects reality rather than overwriting it.

The System section shows both halves: a Hostname Domain row for the domain containers are named under — flagged when macOS is not resolving it yet — and a row per registered domain, which can be unregistered from its context menu. Register DNS Domain with macOS… handles the resolver half on its own, and Open System Configuration opens config.toml in Nova when you would rather edit it by hand.

There is no per-container hostname to set: the hostname is the container's name plus the domain, so name the container (or the compose service) accordingly.

Commands

Under Extensions → Apple Container:

Command What it does
Reload Sidebar Refetch everything
Start / Stop Container Services container system start / stop
Show System Status / Logs Status in a tab, logs followed in your terminal
Register DNS Domain with macOS… Adds the resolver entry, via sudo in your terminal
Open System Configuration Opens Apple Container's config.toml
Compose Up / Down / Build Runs against the workspace's compose file
Build Image from Editor… container build using the Dockerfile in the front editor
Pull Image… / Run Image… Prompts for a reference and runs it in your terminal
Restart Language Server Restarts docker-language-server

Anything long-running or interactive — shells, followed logs, pulls, builds, compose — runs in Terminal or iTerm2 so you can watch it. Everything else runs in the background and reports failures as notifications.

Language support

Syntax highlighting and folding for Dockerfiles (Dockerfile, Containerfile, *.dockerfile) and Compose files (compose.yaml, docker-compose.yml, and YAML files with a top-level services: key), both backed by tree-sitter grammars bundled with the extension.

Completion, hover, validation and linting come from docker-language-server. The binary is about 40 MB, too large to ship inside an extension, so the managed mode downloads the pinned release into the extension's storage the first time it is needed. Point at your own binary instead, or turn the server off, in the extension's preferences.

The Compose syntax is registered under the name dockercompose because that is the language identifier docker-language-server recognises compose files by.

Preferences

Setting Default Notes
container / container-compose path resolved from PATH Set these if you install somewhere unusual
Container Shell /bin/sh Used by Open Shell
Terminal Terminal Or iTerm2
Refresh Interval 5s 0 refreshes only on demand
Start Services Automatically off Runs container system start when the sidebar loads
Group by Compose Project on
Container label / description Name, image and ports What each row shows
Hostname Domain from config.toml Suffix for container hostnames; writes Apple Container's own config
Status Icons Traffic Lights Or toggles, or power symbols
Group Images by Repository on
Show Registry Host off docker.io/library/nginx rather than nginx
Show Infrastructure Images off Apple Container's builder and init images
Detach on Up on --detach for compose up
Run Compose in Terminal on Off runs it in the background instead
Language Server Managed Binary Or a custom path, or disabled

Per-workspace, under Project Settings, you can pin the compose file the compose commands use and the profiles they pass.

Notes and limits

  • container-compose down stops a project's containers but leaves them defined, so they stay in the sidebar as stopped rows until you delete them.
  • Volume rows show their driver and filesystem rather than a size: the backing disk images are sparse, so the reported size is the maximum they may grow to, not what they occupy.
  • A compose project row can only run compose commands when the matching compose file is in the open workspace, since project names are all the containers carry.
  • Changing the hostname domain only affects containers created afterwards, and the services need a restart to pick it up.

Development

./Tools/build-syntaxes.sh   # rebuild the tree-sitter grammars (needs cc and git)
python3 Tools/make-icons.py # regenerate the icon set

Both write into the extension in place. The grammars are pinned to revisions that generate tree-sitter ABI 14, which is what Nova loads.

To run the extension from source, open this folder in Nova and choose Extensions → Activate Project as Extension.

Credits