# How to Mount Volumes in Container: Bind, Named, and Tmpfs Configuration

> Learn how to mount volumes in containers using bind mounts named volumes and tmpfs Explore Docker compatible syntax for your Apple Container projects and get a clear understanding of Linux VM filesystem configuration

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

---

**Apple Container supports three mount types—bind mounts, named volumes, and tmpfs—using Docker-compatible `--mount` syntax parsed by [`Parser.swift`](https://github.com/apple/container/blob/main/Parser.swift) and applied via [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift) to configure the Linux VM filesystem.**

The `apple/container` repository provides a Swift-based container runtime that handles volume mounting through a strict validation pipeline. Whether you are sharing host directories or allocating temporary memory filesystems, the mount configuration follows a standardized parsing flow from CLI arguments to low-level VM configuration.

## Supported Mount Types

Apple Container implements three distinct mount strategies, each handled differently by the internal `VolumeOrFilesystem` abstraction.

### Bind Mounts

**Bind mounts** map a host directory into the container using `virtiofs`. When you specify `type=bind`, the parser in [`Sources/ContainerCLIService/Parser.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCLIService/Parser.swift) converts this internally to a `virtiofs` filesystem type. The source path must exist as a directory on the host, and the parser resolves relative paths against the current working directory using `URL(fileURLWithPath:)` resolution.

### Named Volumes

**Named volumes** provide persistent storage managed by the container runtime. When parsing `type=volume`, the source directive is validated against the `VolumeStorage.volumeNamePattern` defined in [`VolumeConfiguration.swift`](https://github.com/apple/container/blob/main/VolumeConfiguration.swift). If you omit the `src` parameter, [`VolumesService.swift`](https://github.com/apple/container/blob/main/VolumesService.swift) automatically generates an anonymous volume name using `VolumeStorage.generateAnonymousVolumeName()`.

### Tmpfs Mounts

**Tmpfs mounts** create temporary in-memory filesystems that do not persist after container shutdown. These mounts accept `size` (in MiB) and `mode` (octal) options. The parser explicitly rejects any `src` directive for tmpfs mounts, as they exist only in memory without a backing host path.

## CLI Syntax and Examples

The `--mount` flag accepts comma-separated key-value pairs following Docker conventions. The parser normalizes shorthand directives (`src` to `source`, `dst` to `destination`, `ro` to read-only).

### Bind Mount Example

Mount a host directory as read-only:

```bash
container run \
  --name myapp \
  --mount type=bind,src=./src,dst=/app/src,ro \
  myimage:latest

```

In [`Parser.swift`](https://github.com/apple/container/blob/main/Parser.swift), the `Parser.mount(_:,relativeTo:)` function validates that `./src` exists and is a directory before converting it to an absolute URL.

### Named Volume Example

Attach a persistent volume to a database container:

```bash
container run \
  --name db \
  --mount type=volume,src=dbdata,dst=/var/lib/mysql \
  mysql:8

```

If `dbdata` does not exist, [`VolumesService.swift`](https://github.com/apple/container/blob/main/VolumesService.swift) creates it before the container starts.

### Tmpfs Mount Example

Create a 512 MiB temporary filesystem:

```bash
container run \
  --mount type=tmpfs,dst=/tmp,size=512,mode=1777 \
  alpine:latest

```

## Parsing and Validation Pipeline

Understanding how to mount volumes in container environments requires insight into the three-stage internal pipeline.

### Parser.swift Implementation

The `Parser.mount(_:,relativeTo:)` method in [`Sources/ContainerCLIService/Parser.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCLIService/Parser.swift) splits the input string on commas and builds a directives dictionary with default `type=virtiofs`. For bind mounts, it verifies directory existence using `FileManager.fileExists(atPath:isDirectory:)`. For volume mounts, it validates names against the storage pattern or triggers anonymous volume creation.

### RuntimeService.swift Conversion

After parsing, [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift) receives `[VolumeOrFilesystem]` objects and constructs the low-level mount table for the Linux VM. This service handles special cases such as `/dev/shm` size configuration by stripping existing size options and injecting user-specified values:

```swift
if czConfig.mounts[i].destination == "/dev/shm" {
    czConfig.mounts[i].options.removeAll { $0.hasPrefix("size=") }
    czConfig.mounts[i].options.append("size=\(shmSize)")
}

```

### Volume Management

[`VolumesService.swift`](https://github.com/apple/container/blob/main/VolumesService.swift) tracks the lifecycle of named and anonymous volumes. When a container stops, this service ensures proper unmounting and cleanup, as demonstrated in [`Tests/CLITests/Subcommands/Volumes/TestCLIAnonymousVolumes.swift`](https://github.com/apple/container/blob/main/Tests/CLITests/Subcommands/Volumes/TestCLIAnonymousVolumes.swift).

## Programmatic Usage in Swift

You can leverage the parsing logic directly in Swift applications using the Container API service.

### Using Parser.mounts()

Process multiple mount strings programmatically:

```swift
import ContainerAPIService

let rawMounts = [
    "type=bind,src=./assets,dst=/app/assets",
    "type=volume,src=logs,dst=/var/log/app"
]

// Parse and validate the mounts
let mounts = try Parser.mounts(rawMounts, relativeTo: URL(fileURLWithPath: FileManager.default.currentDirectoryPath))

for mount in mounts {
    switch mount {
    case .filesystem(let fs):
        print("Filesystem mount: \(fs.type) from \(fs.source) → \(fs.destination)")
    case .volume(let vol):
        print("Volume mount: \(vol.name) → \(vol.destination) (anonymous: \(vol.isAnonymous))")
    }
}

```

This approach validates paths and volume names before container initialization, catching `ContainerizationError` exceptions for invalid specifications.

## Special Cases and Configuration

### /dev/shm Size Configuration

The runtime normalizes shared memory mounts automatically. As shown in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift), the service detects `/dev/shm` destinations and manages size options explicitly, ensuring the container receives the correct allocation regardless of duplicate specifications in the mount string.

## Summary

- **Apple Container** supports bind mounts (via virtiofs), named volumes, and tmpfs through Docker-compatible `--mount` syntax.
- The **`Parser.mount`** function in [`Parser.swift`](https://github.com/apple/container/blob/main/Parser.swift) validates source directories, resolves relative paths, and distinguishes between filesystem and volume mounts.
- **Anonymous volumes** are generated automatically when volume mounts omit the `src` directive, managed by [`VolumesService.swift`](https://github.com/apple/container/blob/main/VolumesService.swift).
- **Tmpfs mounts** accept `size` and `mode` options but reject source paths, creating temporary in-memory storage.
- **[`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift)** handles low-level VM configuration, including special normalization for `/dev/shm` size options.

## Frequently Asked Questions

### What is the difference between bind mounts and named volumes in Apple Container?

**Bind mounts** directly map host directories into the container via virtiofs, requiring the source path to exist before container start. **Named volumes** are managed by [`VolumesService.swift`](https://github.com/apple/container/blob/main/VolumesService.swift) and provide persistent storage that survives container deletion, with automatic creation if the volume name does not exist.

### How are anonymous volumes created when no source is specified?

When you specify `type=volume` without a `src` directive, [`Parser.swift`](https://github.com/apple/container/blob/main/Parser.swift) triggers `VolumeStorage.generateAnonymousVolumeName()` to create a unique identifier. [`VolumesService.swift`](https://github.com/apple/container/blob/main/VolumesService.swift) then provisions this storage automatically, as verified in [`Tests/CLITests/Subcommands/Volumes/TestCLIAnonymousVolumes.swift`](https://github.com/apple/container/blob/main/Tests/CLITests/Subcommands/Volumes/TestCLIAnonymousVolumes.swift).

### Can I use tmpfs mounts for temporary container storage?

Yes. **Tmpfs mounts** create memory-backed filesystems that do not persist after the container stops. Specify `type=tmpfs` with `dst`, `size`, and optional `mode` parameters. The parser rejects any `src` value for tmpfs mounts since they exist only in memory without host directory backing.

### How does the runtime handle special mounts like /dev/shm?

[`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift) detects `/dev/shm` destinations during configuration and normalizes size options by removing existing `size=` entries and injecting the user-specified value. This ensures consistent shared memory sizing regardless of how the mount string was constructed.