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
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
# Apple Container for Nova
|
||||
|
||||
Manage [Apple Container](https://github.com/apple/container) and
|
||||
[container-compose](https://github.com/mcrich23/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](https://github.com/apple/container) installed
|
||||
(`container` on your `PATH`, or point at it in the extension's preferences)
|
||||
- [container-compose](https://github.com/mcrich23/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](https://github.com/docker/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
|
||||
|
||||
```sh
|
||||
./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
|
||||
|
||||
- Inspired by [Docker Suite](https://gitlab.com/joncoole/nova-docker-suite) by
|
||||
Jonathan Coole.
|
||||
- Bundled grammars:
|
||||
[tree-sitter-dockerfile](https://github.com/camdencheek/tree-sitter-dockerfile)
|
||||
and [tree-sitter-yaml](https://github.com/tree-sitter-grammars/tree-sitter-yaml),
|
||||
both MIT licensed.
|
||||
- Language features from
|
||||
[docker-language-server](https://github.com/docker/docker-language-server),
|
||||
Apache 2.0 licensed, downloaded at runtime rather than bundled.
|
||||
|
||||
Reference in New Issue
Block a user