# How to Manage Disk Usage and Prune Unused Container Images in Apple Container

> Manage disk usage and prune unused container images in Apple Container. Safely reclaim space using prune commands like `container prune` and `image prune`.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-07-04

---

**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`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/VolumePrune.swift) verifies `volume.attachments.isEmpty` before deletion, ensuring data persistence for attached volumes. Network pruning follows similar logic in [`NetworkPrune.swift`](https://github.com/apple/container/blob/main/NetworkPrune.swift), removing only unattached networks.

## Practical Usage Examples

Execute prune operations from the command line:

```bash

# 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:

```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`](https://github.com/apple/container/blob/main/ImagePrune.swift), [`ContainerPrune.swift`](https://github.com/apple/container/blob/main/ContainerPrune.swift), [`VolumePrune.swift`](https://github.com/apple/container/blob/main/VolumePrune.swift), and [`NetworkPrune.swift`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/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`](https://github.com/apple/container/blob/main/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.