new features

This commit is contained in:
Mark Gregory
2026-11-08 17:28:29 +00:00
parent 8c34e965fd
commit ecfa74a35f
30 changed files with 1651 additions and 27 deletions
+86 -27
View File
@@ -1,37 +1,96 @@
# Apple Container Compose — Xcode macOS application (prototype)
# AppleContainerCompose — Native Xcode project (developer preview)
A native SwiftUI macOS front end for Apple's `container` runtime. Includes a bundled Python Compose-style orchestration engine from the initial MVP.
A SwiftUI macOS application and **native Swift** `accompose` CLI that operate Apple's `container` runtime. No Python, PyYAML, ServBay, Docker Desktop, or Docker daemon is needed. Both targets compile the same `ComposeCore.swift` orchestration implementation and use the Yams Swift package for YAML parsing.
## Requirements
- Apple silicon Mac running macOS 26 or newer
- Xcode 26 or newer
- Apple's `container` CLI installed and configured
- Python 3 with PyYAML available to the **python3** interpreter launched by the app
- Internet access on first Xcode build to resolve the Yams Swift package
## Open and build
1. Open `AppleContainerCompose.xcodeproj` in Xcode.
2. Select the `AppleContainerCompose` scheme and `My Mac` destination.
3. Build and run (Command-R).
4. Click **Open YAML** and choose a Compose file (sample in `Examples/compose.yaml`).
5. Use **Up**, **Down**, **Status**, **Logs**, **Restart**, **Pull Images**, or **Build Images**.
- Apple silicon, macOS 26+, Xcode 26+
- Apple's [`container`](https://github.com/apple/container) CLI installed, with a configured kernel (`container system start`)
- Internet on first build to fetch the Yams Swift package
## Python dependency
The bundled engine imports PyYAML. Install it for the Python interpreter available in your macOS app's PATH. For example, using Homebrew Python:
## Build and run GUI
```sh
brew install python
/opt/homebrew/bin/python3 -m venv ~/.local/share/accompose-venv
~/.local/share/accompose-venv/bin/pip install PyYAML
Open `AppleContainerCompose.xcodeproj`, select the `AppleContainerCompose` scheme and run. Use **Open YAML** to load `Examples/compose.yaml`, then Up / Down / Status / Logs. The GUI invokes the same native Swift engine as the CLI, not Python.
## Install command line utility
From Terminal, in the project root:
```bash
./Scripts/install-cli.sh
accompose doctor
cd Examples
accompose up -d
accompose ps
accompose logs
accompose down
```
The current app executes `python3` from PATH, not the venv automatically. Install PyYAML into that interpreter, or modify `executeEngine` to use `~/.local/share/accompose-venv/bin/python` (recommended for isolated dependencies).
The installer builds the `accompose` Xcode scheme in Release and copies the binary to `/opt/homebrew/bin/accompose` (override `PREFIX=/your/prefix`). It asks for administrator permissions only if the destination directory is not writable. Add the prefix's `bin` directory to your PATH if needed.
## Current implementation scope
- Native Xcode project with SwiftUI project browser, service summary, and command output
- Compose YAML parsing for service listing using Yams
- Bundled MVP engine: up/down, start/stop/restart, ps/logs, build/pull, state, dependencies, networks and volumes
- App process runs without macOS sandbox because it invokes the host's container CLI
## CLI usage
## Limitations
This is a development prototype, not a fully native orchestration engine or production-grade Docker Compose replacement. Runtime integration is not tested on macOS here. The Python engine requires PyYAML; service status is currently based on project state; logs are batch output, not continuous streaming; health checks, advanced Compose compatibility, restart supervision, service scaling and secure secrets management remain future work. The UI's restart action restarts the whole project. Consult Apple's `container` version for supported CLI flags.
```
accompose init
accompose [-f compose.yaml] [-p project] config
accompose [-v|-vv|-vvv] up [-d|--detach] [--build]
accompose down [--volumes]
accompose ps
accompose pull
accompose build
accompose logs [service]
accompose start|stop|restart [service]
accompose exec SERVICE COMMAND [ARG ...]
accompose doctor
```
The default file discovery order is `compose.yaml`, `compose.yml`, `docker-compose.yaml`, `docker-compose.yml`. `.env` substitution, build contexts, Dockerfiles, service dependency ordering, environment variables, published ports, bind mounts, named volumes, and custom networks have initial support. Names are scoped by project.
## Limitations / important safety notes
This is an **early developer preview**, not a drop-in Docker Compose implementation. Only a subset of Compose YAML is parsed. Long-form mounts/ports, secrets, service health gating, robust reconciliation, profiles, scaling, live `logs -f`, restart supervision, and full network aliases are **not implemented**. A service with multiple networks only attaches to its first network; the CLI prints a warning. Restart policies are parsed but **not enforced**. `up` does not update an existing container when YAML changes: use `down` then `up`. `ps` currently lists all Apple containers, not just the project. Named volumes are not removed by `down` unless `--volumes` is provided. `down` may stop/remove project containers: check the project name before running it. The installer never automatically downloads or configures an unverified kernel.
Debug and Release builds of both Xcode targets and real Apple container runtime checks passed on macOS. See `Validation/VALIDATION.md` for the environment, checks and limitations.
## Updated developer preview: CLI rename and cleanup
The CLI target and installer are now named `accompose`. Re-run `./Scripts/install-cli.sh` after replacing your old project. The older `acccompose` executable is not automatically deleted. Verify using `accompose --help`.
Additional commands:
```sh
accompose import ./docker-compose.yml # validate existing YAML without modifying it
accompose import ~/Projects/example # validate directory's default Compose file
accompose clean web --dry-run # preview deletion
accompose clean web # delete managed service container
accompose clean --all --dry-run # preview project container deletion
accompose clean --all # delete project containers
accompose prune --images # request runtime unused-image cleanup
```
The sample `Examples/site/index.html` is included to prevent the original Nginx bind mount failure. Missing directory bind sources are created during `up`; do not use a missing *file* bind source because it will be created as a directory.
### Compatibility limitations
This is **not** full Docker Compose support. Import validates only the subset of YAML handled by ComposeCore. Unrecognized service keys cause an explicit error rather than being silently ignored. Import does not yet persist projects to a GUI library, multi-file merging and YAML extension semantics are incomplete, and clean only deletes managed project containers (not host data, volumes, images or networks). Image pruning relies on the installed Apple `container` version supporting `container image prune`. The kernel and all host bind files are preserved. `--dry-run` is only supported for clean and prune. The detached/foreground lifecycle has been integration-tested on the runtime version recorded in `Validation/VALIDATION.md`.
## Foreground and detached mode fix
- `accompose up` streams each service's logs live and stays attached until log followers finish or the command is interrupted.
- `accompose up -d` and `accompose up --detach` return after startup, leaving containers running.
- `-v`, `-vv` and `-vvv` change diagnostics only. They work before or after `up`, for example `accompose -vvv up -d` and `accompose up -d -vvv`.
- Ctrl+C (or SIGTERM) in foreground mode stops managed containers in reverse dependency order using the runtime's graceful `stop`; containers are preserved for subsequent `up`. Interrupted startup stops the containers reached so far.
- Existing stopped containers are restarted. Configuration changes still require `down` and `up`.
- The GUI's Up action retains its asynchronous, detached engine behavior.
- The runtime executable is resolved from PATH first, with Homebrew/system fallback paths.
Verbosity levels add mode/project details, Compose file location, then startup order. They do not change container execution mode. `logs` remains a snapshot command; foreground `up` uses independent live log followers. Multiple service logs share the terminal without added service prefixes.
To rerun the isolated regression suite (Python 3 is needed only for tests):
```sh
python3 Tests/cli_regression.py /absolute/path/to/built/accompose
```
The suite substitutes a temporary fake runtime and never changes real containers.