How to Utilize Anonymous Volumes and Manage Their Lifecycle in apple/container
Anonymous volumes in apple/container automatically provision persistent storage with UUID-based names when you omit the source path in a mount specification, persist after container exit, and require manual deletion via container volume delete or container volume prune when no longer referenced.
Anonymous volumes provide a lightweight storage mechanism in the apple/container ecosystem that eliminates the need for manual naming while maintaining full lifecycle control. When you run a container with a mount that specifies only a destination path, the CLI generates a unique identifier and persists data to the VolumeStorage directory exactly like a named volume. Understanding how these volumes are created in VolumesService._create, tracked via the VolumeConfiguration model, and safely destroyed is essential for effective storage management.
Creating Anonymous Volumes
Anonymous volumes are generated automatically whenever you provide a mount specification without a source name. According to the source code in Sources/Services/ContainerAPIService/Client/Parser.swift (lines 35-46), the parser sets ParsedVolume.isAnonymous = true when the source field is empty.
You can create an anonymous volume using either Docker-style syntax or the mount flag:
# Docker-style syntax creates an anonymous volume mounted at /data
container run -v /data alpine:latest
# Alternative using --mount syntax without source
container run --mount type=volume,dst=/data alpine:latest
When executing these commands, VolumesService._create generates a UUID-based name following the pattern anon-{36-char-uuid} and stores the volume in the runtime's VolumeStorage directory. The VolumeConfiguration model marks the volume with isAnonymous = true (see Sources/Services/ContainerAPIService/Server/Volumes/VolumesService.swift, lines 55-62).
Lifecycle and Persistence Characteristics
Automatic Generation and Naming
Unlike named volumes that require explicit identification, anonymous volumes receive automatically generated identifiers. The system creates a directory named anon-<uuid> and records this in the volume configuration, making the volume discoverable through standard CLI commands without requiring you to memorize custom names.
Persistence Beyond Container Exit
Anonymous volumes persist on disk exactly like named volumes. They remain available after the container exits and are not automatically garbage collected. This behavior ensures data survival across container restarts and allows you to re-attach the storage to new container instances by referencing the generated ID.
Visibility and Inspection
You can identify anonymous volumes using the list command with JSON output, which reveals the isAnonymous flag added during VolumeResource serialization (lines 56-57 of VolumesService.swift):
container volume inspect anon-1e2f3d4c-5b6a-7d8e-9f0a-b1c2d3e4f5g6
The output includes "isAnonymous": true, distinguishing these volumes from explicitly named ones.
Managing Anonymous Volume Lifecycle
Listing and Identifying Anonymous Volumes
To view all anonymous volumes and extract their IDs for scripting:
# Show only volume IDs (quiet mode) and filter for anonymous
container volume list -q | grep anon
This returns the UUID-based names that you can use in subsequent commands.
Re-attaching to New Containers
Since anonymous volumes are functionally identical to named volumes after creation, you can mount them in new containers by specifying the generated ID:
# Capture the most recent anonymous volume ID
VOL=$(container volume list -q | grep anon | tail -n1)
# Re-attach to a new container
container run -v $VOL:/data alpine:latest
The same storage is now accessible inside the new container at the specified mount point.
Manual Deletion and Safety Guards
Anonymous volumes are not removed when running containers with --rm. You must explicitly delete them. The system implements safety checks in VolumesService._delete (lines 76-86) that atomically verify no containers reference the volume before allowing deletion:
# Delete a specific anonymous volume
container volume delete anon-1e2f3d4c-5b6a-7d8e-9f0a-b1c2d3e4f5g6
If the volume remains attached to any container (running or stopped), the command fails with a "volume in use" error. This prevents accidental data loss.
For bulk cleanup, use the prune command to remove all unused volumes:
# Remove all volumes not attached to any container
container volume prune
This command safely identifies volumes with zero container references and reclaims disk space.
Practical Code Examples
Creating and Verifying an Anonymous Volume
# Start a container with an anonymous volume
container run -v /app/data --name test alpine:latest touch /app/data/file.txt
# List volumes to see the generated ID
container volume list
Inspecting Volume Metadata
# Get detailed JSON including the isAnonymous flag
container volume inspect $(container volume list -q | grep anon | head -n1)
Sample output excerpt:
{
"name": "anon-1e2f3d4c-5b6a-7d8e-9f0a-b1c2d3e4f5g6",
"driver": "local",
"isAnonymous": true,
"mountpoint": "/var/lib/container/volumes/anon-1e2f3d4c-5b6a-7d8e-9f0a-b1c2d3e4f5g6"
}
Complete Lifecycle Workflow
# 1. Create container with anonymous volume
CID=$(container run -d -v /data alpine:latest sh -c "echo 'persistent data' > /data/file.txt")
# 2. Extract the volume ID from the container JSON
VOL=$(container inspect $CID | grep -o 'anon-[a-f0-9-]\{36\}')
# 3. Remove container (volume persists)
container rm $CID
# 4. Use volume in new container
container run -v $VOL:/data alpine:latest cat /data/file.txt
# 5. Clean up when done
container volume delete $VOL
Summary
- Anonymous volumes generate UUID-based names (
anon-*) automatically when you specify a mount destination without a source incontainer runcommands. - They persist after container exit and are tracked in
VolumeConfigurationwithisAnonymous = true, visible incontainer volume listand inspect output. - The
VolumesService._deletefunction enforces safety by blocking deletion of volumes still attached to any container (running or stopped). - Manual cleanup is required using
container volume delete <id>orcontainer volume prune, as the--rmflag does not remove anonymous volumes.
Frequently Asked Questions
How do anonymous volumes differ from named volumes in apple/container?
Anonymous volumes function identically to named volumes in terms of storage mechanics and persistence. The only difference is the naming convention—anonymous volumes receive auto-generated UUIDs (anon-<uuid>) while named volumes use user-specified identifiers. Both are stored in the same VolumeStorage directory and tracked through the VolumeConfiguration model, but anonymous volumes set isAnonymous = true during creation in VolumesService._create.
Why isn't my anonymous volume deleted when I use container run --rm?
The --rm flag only removes the container layer, not associated volumes. According to the implementation in Sources/Services/ContainerAPIService/Server/Volumes/VolumesService.swift, anonymous volumes are designed to persist beyond the container lifecycle to prevent accidental data loss. You must explicitly delete them using container volume delete or clean up unused volumes with container volume prune after confirming no containers reference them.
How can I identify which anonymous volumes are safe to delete?
Run container volume list to see all volumes, then use container volume inspect <id> to check the "isAnonymous" field. To verify safety for deletion, attempt to remove the volume—the atomic check in _delete (lines 76-86) will reject the operation if any container (running or stopped) still references the volume, ensuring you cannot delete actively used storage.
Can I convert an anonymous volume to a named volume?
While there is no direct "rename" command in the CLI, you can achieve equivalent functionality by creating a new named volume and copying data from the anonymous volume, or by referencing the anonymous volume's ID in subsequent container runs as you would with a named volume. The UUID-based name functions as a stable identifier for re-attachment regardless of the volume type.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →