# Lifecycle of Anonymous Volumes in Container: Complete Technical Guide

> Explore the lifecycle of anonymous volumes in Apple's container project. Learn how they persist indefinitely and discover manual deletion methods to manage storage effectively.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: deep-dive
- Published: 2026-06-20

---

**Anonymous volumes in the Apple Container project persist indefinitely after container exit and require manual deletion via `container volume rm` or `container volume prune`, even when the container is started with the `--rm` flag.**

The lifecycle of anonymous volumes in `container` follows a distinct path from creation through manual cleanup. Unlike named volumes, these storage objects are auto-generated when mounting paths without specifying a source, yet they deliberately survive container termination to ensure data durability. This guide examines the implementation details—from UUID generation in the parser to the `VolumeInUse` protection mechanisms—based on the actual source code in the `apple/container` repository.

## How Anonymous Volumes Are Created

Anonymous volumes are instantiated when you execute a `container run` command with a mount flag that omits the source component, such as `-v /data` or `--mount type=volume,dst=/data`.

### Detection by the CLI Parser

In [`Sources/Services/ContainerAPIService/Client/Parser.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Client/Parser.swift), the client-side parser identifies volume mounts lacking a source path. Upon detection, it initiates the anonymous volume workflow rather than binding to a named volume or host directory. This triggers the generation of a unique identifier and the creation of a `VolumeConfiguration` object marked with special metadata.

### UUID Generation and Naming

The system generates a lowercase UUID string via `VolumeStorage.generateAnonymousVolumeName()` located in [`Sources/ContainerResource/Volume/VolumeConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Volume/VolumeConfiguration.swift) (lines 152-155). This function produces a unique name that serves as the volume’s identifier:

```swift
// From VolumeConfiguration.swift
static func generateAnonymousVolumeName() -> String {
    return UUID().uuidString.lowercased()
}

```

The resulting UUID (e.g., `f47ac10b-58cc-4372-a567-0e02b2c3d479`) becomes the volume’s name, stored within the `VolumeConfiguration` structure.

## Anonymous Volume Identification and Metadata

### The Anonymous Label Marker

The system distinguishes anonymous volumes from named ones through reserved metadata. In [`Sources/ContainerResource/Volume/VolumeConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Volume/VolumeConfiguration.swift) (lines 99-106), the `labels` dictionary contains the key `com.apple.container.resource.anonymous`. The presence of this label causes the `isAnonymous` computed property to return `true`, enabling the runtime to apply specific persistence and cleanup policies throughout the lifecycle.

```swift
// VolumeConfiguration.swift defines the identifying label
static let anonymousLabel = "com.apple.container.resource.anonymous"

```

## Runtime Behavior and Persistence

### Survival Beyond Container Exit

Anonymous volumes **do not** auto-remove when the container exits. This is a deliberate design choice that differs from Docker’s default behavior. Even when starting a container with the `--rm` flag, the volume remains on the host filesystem under the container’s data directory.

Tests in [`Tests/CLITests/Subcommands/Volumes/TestCLIAnonymousVolumes.swift`](https://github.com/apple/container/blob/main/Tests/CLITests/Subcommands/Volumes/TestCLIAnonymousVolumes.swift) (lines 117-143) verify this persistence, confirming that running `container run --rm` with an anonymous volume increases the volume count and preserves data across container exits.

### Listing and Reusing Anonymous Volumes

Because anonymous volumes receive UUID-based names rather than user-friendly labels, you retrieve them using the quiet list flag:

```bash
container volume list -q

```

This outputs the generated UUIDs, allowing you to mount an existing anonymous volume in new containers by referencing its ID directly:

```bash
container run -v f47ac10b-58cc-4372-a567-0e02b2c3d479:/data myimage

```

## Manual Cleanup Requirements

### Removing Specific Volumes

Delete an anonymous volume by specifying its UUID:

```bash
container volume rm f47ac10b-58cc-4372-a567-0e02b2c3d479

```

The runtime validates usage before deletion. As implemented in [`Sources/ContainerResource/Volume/VolumeConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Volume/VolumeConfiguration.swift) (lines 110-115), the system checks whether the volume is attached to any container (running or stopped). If still in use, the command fails with a `VolumeInUse` error.

### Pruning Unused Volumes

To bulk-remove all anonymous volumes not currently attached to containers:

```bash
container volume prune

```

This command filters volumes based on the `isAnonymous` property and usage status, reclaiming disk space from orphaned storage while respecting active attachments.

## Summary

- Anonymous volumes are created automatically when mounting paths without sources, receiving UUID-based names via `VolumeStorage.generateAnonymousVolumeName()` in [`VolumeConfiguration.swift`](https://github.com/apple/container/blob/main/VolumeConfiguration.swift).
- The `com.apple.container.resource.anonymous` label stored in the volume’s metadata distinguishes anonymous volumes from named ones via the `isAnonymous` property.
- Volumes persist indefinitely after container exit, ignoring the `--rm` flag, as verified by test cases in [`TestCLIAnonymousVolumes.swift`](https://github.com/apple/container/blob/main/TestCLIAnonymousVolumes.swift).
- Users must manually delete anonymous volumes using `container volume rm <uuid>` or `container volume prune`.
- The runtime prevents deletion of attached volumes, returning `VolumeInUse` errors when the volume remains linked to any container.

## Frequently Asked Questions

### Do anonymous volumes delete automatically when using `--rm`?

No. Anonymous volumes survive container termination even when started with the `--rm` flag. This deliberate design choice ensures data persistence across container restarts. According to the [`docs/command-reference.md`](https://github.com/apple/container/blob/main/docs/command-reference.md), you must explicitly remove them using `container volume rm` or `container volume prune`.

### How can I identify which volumes are anonymous?

Anonymous volumes appear as lowercase UUID strings when running `container volume list -q`. Internally, the system identifies them via the `com.apple.container.resource.anonymous` label in [`VolumeConfiguration.swift`](https://github.com/apple/container/blob/main/VolumeConfiguration.swift), which sets the `isAnonymous` property to `true`.

### Can I mount an existing anonymous volume in a new container?

Yes. While anonymous volumes receive auto-generated UUID names, you can reuse them by specifying the UUID as the source in your mount command. First retrieve the ID using `container volume list -q`, then mount it explicitly: `container run -v <uuid>:/path ...`.

### What happens if I try to delete an anonymous volume still attached to a container?

The deletion fails with a `VolumeInUse` error. According to [`Sources/ContainerResource/Volume/VolumeConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Volume/VolumeConfiguration.swift) (lines 110-115), the volume service checks whether the volume is attached to any container (running or stopped) before permitting removal. You must stop and remove the dependent container first.