How to Manage Disk Usage and Prune Unused Container Images in Apple Container
Prune unused container images, stopped containers, volumes, and networks using the container prune, image prune, volume prune, and network prune commands to reclaim disk space safely.
The Apple Container repository provides a Swift-based container runtime that implements Docker-style resource management. When you need to manage disk usage and prune unused container images, the toolchain offers specialized sub-commands that safely identify and remove dangling resources while preserving running workloads.
How Prune Commands Work Under the Hood
Resource Discovery
Each prune command begins by enumerating objects from the on-disk Store. Located in Sources/ContainerCommands/*, the implementations walk their respective domains—containers, images, volumes, or networks—to build a complete inventory of potentially removable resources.
Eligibility Verification
Before deletion, the system validates resource eligibility through specific safety checks:
- Containers: Only stopped containers qualify (
container.state.isRunning == false). Running containers are never pruned. - Images: An image is considered dangling when no container references it. The
-aflag extends this to include tagged images with no active references. - Volumes: Volumes require empty attachment lists (
volume.attachments.isEmpty) to be eligible for removal. - Networks: Networks must have zero container attachments to pass the safety check.
Safe Deletion and Reporting
The commands invoke lower-level store APIs—store.removeContainer, _removeImage, _removeVolume, and _removeNetwork—to execute deletions. Errors are collected during the process but do not abort the operation; all pruned resource identifiers are printed to stdout in Docker-compatible format (one ID per line).
Pruning Container Images
Removing Dangling Images
The image prune command, implemented in Sources/ContainerCommands/Image/ImagePrune.swift, targets images lacking container references. This removes intermediate build layers and untagged images that consume disk space without providing utility.
Aggressive Pruning with the -a Flag
Adding the -a (or --all) flag removes all unused images, including those with tags but no running references. This is implemented in the same ImagePrune.swift file by modifying the reference check logic to ignore tag status when the flag is present.
Pruning Containers, Volumes, and Networks
Stopped Container Removal
The container prune command (top-level prune in ContainerPrune.swift) removes stopped containers while preserving running instances. This implementation checks container.state.isRunning before invoking store.removeContainer.
Volume and Network Cleanup
Volume pruning in VolumePrune.swift verifies volume.attachments.isEmpty before deletion, ensuring data persistence for attached volumes. Network pruning follows similar logic in NetworkPrune.swift, removing only unattached networks.
Practical Usage Examples
Execute prune operations from the command line:
# Remove all stopped containers
container prune
# Remove dangling images only
image prune
# Remove all unused images (including tagged)
image prune -a
# Remove unused volumes
volume prune
# Remove unused networks
network prune
Programmatically invoke prune logic from Swift:
import ContainerCommands
// Programmatically prune images
do {
let prune = ImagePrune()
try prune.run()
print("Image prune completed successfully.")
} catch {
print("Prune failed: \(error)")
}
Summary
- Use
image pruneto remove dangling images andimage prune -ato remove all unused images according to the Apple Container source code. - The prune commands reside in
Sources/ContainerCommands/with specific implementations inImagePrune.swift,ContainerPrune.swift,VolumePrune.swift, andNetworkPrune.swift. - Safety checks prevent deletion of running containers and attached volumes through state validation (
isRunning,attachments.isEmpty). - Errors during pruning are collected and reported without aborting the entire operation.
- Integration tests in
Tests/IntegrationTests/verify prune behavior respects usage constraints.
Frequently Asked Questions
What is the difference between image prune and image prune -a?
Standard image prune removes only dangling images—those without tags and not referenced by any container. The -a flag removes all unused images, including tagged images that have no container references. Both commands are implemented in Sources/ContainerCommands/Image/ImagePrune.swift with logic that checks image references against the container store.
Will pruning delete containers that are currently stopped?
Yes, container prune specifically targets stopped containers by checking container.state.isRunning == false in ContainerPrune.swift. Running containers are explicitly excluded from the deletion set, making it safe to prune while active workloads remain operational.
How does the system prevent accidental deletion of volumes in use?
Volume pruning in VolumePrune.swift requires volume.attachments.isEmpty to be true before removal. If a volume is attached to any container—even a stopped one—it remains preserved. This safety mechanism is verified in integration tests like Tests/IntegrationTests/Volumes/TestCLIVolumesSerial.swift.
Can I run prune commands programmatically from Swift?
Yes, you can instantiate prune classes directly from the ContainerCommands module. For example, create an ImagePrune() instance and call try prune.run() to execute the pruning logic within your application. This approach uses the same underlying implementation as the CLI commands.
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 →