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 -a flag 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 prune to remove dangling images and image prune -a to remove all unused images according to the Apple Container source code.
  • The prune commands reside in Sources/ContainerCommands/ with specific implementations in ImagePrune.swift, ContainerPrune.swift, VolumePrune.swift, and NetworkPrune.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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →