Feat/native volumes#106
Open
w1zdun wants to merge 2 commits into
Open
Conversation
Named volumes were previously emulated by bind-mounting host directories under ~/.containers/Volumes/<project>/, which breaks containers whose entrypoint chowns its data directory (virtiofs forbids chown — e.g. mysql dies with 'changing ownership of /data: Operation not permitted'). The container CLI (>= 0.12) supports volumes natively, so: - top-level 'volumes:' entries are created via ClientVolume.create with docker-compose naming (<project>_<key>, explicit 'name:' verbatim, 'external:' never created), idempotently - named volume references in services mount as -v <nativeName>:<dest>, fixing a bug where the destination's parent directory was mounted instead of the destination itself - named volumes referenced by services but not declared top-level are created on demand (docker compose errors here; this tool stays tolerant) - 'down -v/--volumes' removes the project's named volumes (and the containers, since a referenced volume cannot be deleted), skipping external ones
Contributor
There was a problem hiding this comment.
Pull request overview
This PR switches named-volume handling from “emulated host directories under ~/.containers/Volumes/... bind-mounted via virtiofs” to native Apple container volumes, addressing virtiofs chown failures for common database images and adding down -v/--volumes support to remove project volumes.
Changes:
- Add named-volume classification + Docker Compose–style name resolution (
<project>_<key>, honorname:, skip creation/removal forexternal: true). - Update
composeVolumeToRunArgsto emit-v <nativeName>:<destination>[:mode]for named volumes (and fix destination-parent mounting bug). - Add
down -v/--volumesparsing and implementation to remove the project’s named volumes (including on-demand ones).
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
Tests/Container-Compose-StaticTests/HelperFunctionsTests.swift |
Updates volume arg tests for new signature and adds coverage for named-volume mapping + resolution helpers. |
Tests/Container-Compose-StaticTests/ComposeBuildParsingTests.swift |
Adds CLI parsing tests for ComposeDown -v/--volumes. |
Sources/Container-Compose/Helper Functions.swift |
Introduces named-volume detection + resolution and updates volume-to-run-args generation to use native volumes. |
Sources/Container-Compose/Commands/ComposeUp.swift |
Creates native volumes up-front and on-demand; maintains a mapping used when building container run args. |
Sources/Container-Compose/Commands/ComposeDown.swift |
Adds -v/--volumes and implements named-volume removal logic. |
.gitignore |
Ignores /tmp/. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+144
to
+155
| // Also remove named volumes that `up` created on demand for service | ||
| // references not declared top-level. | ||
| for (_, service) in services { | ||
| for volume in service.volumes ?? [] { | ||
| guard let source = volume.split(separator: ":", maxSplits: 2).map(String.init).first, | ||
| isNamedVolumeSource(source), !handledKeys.contains(source) | ||
| else { continue } | ||
| handledKeys.insert(source) | ||
| let (nativeName, _) = resolveNamedVolume(key: source, config: nil, projectName: projectName) | ||
| await removeNamedVolume(key: source, name: nativeName) | ||
| } | ||
| } |
| @Argument(help: "Specify the services to stop") | ||
| var services: [String] = [] | ||
|
|
||
| @Flag(name: [.customShort("v"), .customLong("volumes")], help: "Remove named volumes declared in the compose file") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Named volumes were emulated as host directories under
~/.containers/Volumes/...bind-mounted via virtiofs. Containers whose entrypointchowns its data directory (MySQL,Postgres, most databases) die on virtiofs (
chown: Operation not permitted). Apple container ≥ 0.12 supports volumes natively, exposed by the pinned dependency viaClientVolume.Changes:
volumes:are created as native volumes named<project>_<key>(docker compose naming parity);external: truevolumes are never created; explicitname:ishonored. Creation is idempotent — existing volumes are detected via
ClientVolume.list()and an "already exists" error from create is tolerated.is kept).
composeVolumeToRunArgspasses-v <nativeName>:<destination>[:mode]for named volumes — this also fixes a pre-existing bug where the named-volume branch mounted theparent of the destination (
deletingLastPathComponent). Bind-mount behavior is byte-for-byte unchanged, covered by the existing tests.down -v/--volumesflag removes the project's named volumes (including on-demand ones, skipping external). Containers are removed first, since a volume cannot bedeleted while a container references it — matching
docker compose down, which always removes containers.Note: unlike docker, Apple container does not populate a freshly created volume from the image's directory content — that is a runtime limitation, not addressed here.