# How to Use Volumes and Bind Mounts for File Sharing with Apple Container

> Learn to use volumes and bind mounts for file sharing in Apple containers. Map host directories or create persistent volumes for seamless data sharing across container instances.

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

---

**Use the `--volume` flag to map host directories directly into containers, or create persistent named volumes with `container volume create` to share data across container restarts and instances.**

The `container` CLI from Apple's open-source repository provides a lightweight virtualization runtime for running OCI-compatible containers on macOS. Learning how to use volumes and bind mounts for file sharing is essential for persisting application state, sharing configuration files from the host, and coordinating data between multiple container instances. This guide documents the exact syntax, underlying architecture, and lifecycle management commands found in the source code.

## Bind Mounts vs. Named Volumes

`container` implements three distinct storage mechanisms for exposing data to containers, each serving different persistence and sharing requirements.

### Bind Mounts (Direct Host Access)

**Bind mounts** directly map a directory or file from the macOS host into the container's filesystem using absolute paths. According to [`docs/how-to.md`](https://github.com/apple/container/blob/main/docs/how-to.md), the CLI translates `--volume` flags into a bind-mount that is passed to the underlying **Containerization** runtime, which creates a virtual block device for the container VM and attaches the host directory as an **FS bind** inside that VM.

The syntax requires an absolute pathname:

```bash
--volume <host-path>:<container-path>

```

Host paths must exist before executing `container run`, and the container sees files with the same permissions as the host user.

### Named Volumes (Managed Persistence)

**Named volumes** are persistent storage objects managed by `container` via the `container volume` sub-command family documented in [`docs/command-reference.md`](https://github.com/apple/container/blob/main/docs/command-reference.md) (lines 862-970). Unlike bind mounts, these are not tied to specific host paths but are instead logical volumes that survive container removal and can be attached to multiple containers simultaneously.

Create them with specific filesystem options:

```bash
container volume create --opt size=5g --opt journal=ordered mydata

```

### Anonymous Volumes (Automatic Storage)

When you specify a target path without a source (e.g., `-v /app/data`), `container` automatically creates an **anonymous volume** with a UUID-based name prefix (`anon-…`). As noted in [`docs/command-reference.md`](https://github.com/apple/container/blob/main/docs/command-reference.md) (lines 909-921), these volumes persist until explicitly deleted using `container volume delete` or `container volume prune`.

## Command Syntax and Architecture

The `container run` command supports two equivalent flag styles for mounting storage, both documented in the *Share host files* section of [`docs/how-to.md`](https://github.com/apple/container/blob/main/docs/how-to.md) (lines 36-53).

**Short form (`--volume` or `-v`):**

```bash
container run -v "${HOME}/Desktop/assets:/content/assets" ...

```

**Explicit form (`--mount`):**

```bash
container run --mount source="${HOME}/Desktop/assets",target=/content/assets ...

```

The `--mount` syntax uses comma-separated `key=value` pairs, which improves readability when combining multiple options. Both methods ultimately trigger the same VM-level bind-mount mechanism described in [`docs/technical-overview.md`](https://github.com/apple/container/blob/main/docs/technical-overview.md).

**Special case:** The `--ssh` flag shortcuts this machinery to mount the macOS SSH socket into containers, demonstrating that any host file can be exposed without additional plumbing ([`docs/how-to.md`](https://github.com/apple/container/blob/main/docs/how-to.md), lines 60-62).

## Practical Usage Examples

### Sharing Host Files with Bind Mounts

Map a local directory into a container to access assets or source code during development:

```bash

# Create test data on the host

mkdir -p "${HOME}/Desktop/assets"
echo '<svg>...</svg>' > "${HOME}/Desktop/assets/link.svg"

# Run container with bind mount

container run \
  --volume "${HOME}/Desktop/assets:/content/assets" \
  docker.io/python:alpine \
  ls -l /content/assets

```

The output confirms the file appears inside the container at `/content/assets`.

### Creating and Using Named Volumes

Named volumes provide durable storage independent of container lifecycle:

```bash

# Create a 5 GiB volume with ext4 journaling

container volume create \
  --opt size=5g \
  --opt journal=ordered \
  mydata

# Attach to a container and write data

container run \
  -v mydata:/app/data \
  docker.io/alpine:latest \
  touch /app/data/marker.txt

# Verify persistence in a new container instance

container run \
  -v mydata:/app/data \
  docker.io/alpine:latest \
  cat /app/data/marker.txt

```

### Handling Anonymous Volumes

Anonymous volumes are ideal for temporary cache directories that should persist across container restarts but not clutter the host filesystem:

```bash

# Trigger automatic volume creation

container run -v /tmp/cache docker.io/alpine:latest touch /tmp/cache/file

# Locate the generated name (format: anon-<uuid>)

VOL=$(container volume list -q | grep anon)
echo "Anonymous volume: $VOL"

# Clean up when no longer needed

container volume delete "$VOL"

```

### Volume Lifecycle Management

Manage persistent storage using the `container volume` subcommands:

```bash

# List all volumes (named and anonymous)

container volume list

# Inspect metadata and configuration in JSON format

container volume inspect mydata

# Remove a specific unused volume

container volume delete mydata

# Remove all unused volumes

container volume prune

```

## Summary

- **Bind mounts** (`-v /host/path:/container/path`) map absolute host paths directly into the container VM filesystem, requiring the path to exist before running the container.
- **Named volumes** created via `container volume create` persist data across container deletions and support configuration options like size limits and filesystem journaling.
- **Anonymous volumes** are auto-generated when specifying only a container path, receiving UUID-based names (`anon-…`) and persisting until manually pruned.
- The `--mount` syntax offers an explicit `key=value` alternative to `--volume`, improving readability for complex mount configurations.
- All volume mechanisms leverage the same underlying Containerization runtime architecture that attaches host directories as FS binds inside the virtual machine.

## Frequently Asked Questions

### What is the difference between `--volume` and `--mount` syntax in container?

Both flags achieve the same underlying bind-mount behavior, but `--volume` uses a concise colon-separated format (`host:container`) while `--mount` uses explicit comma-separated key-value pairs (`source=...,target=...`). The `--mount` syntax reduces ambiguity when specifying additional options and is preferred for complex configurations or named volume references.

### Why must host paths be absolute when using bind mounts?

The `container` CLI requires absolute pathnames for host directories to ensure the Containerization runtime can correctly resolve and attach the filesystem to the virtual machine's block device. Relative paths are rejected because the daemon process runs in a different context than the user's shell.

### How do I share data between multiple containers?

Create a **named volume** using `container volume create <name>` and attach it to multiple containers using `-v <name>:/path`. Unlike bind mounts, named volumes are managed by the `container` daemon and persist independently of any single container's lifecycle, allowing seamless data sharing across container instances.

### Can I limit the size of a persistent volume?

Yes. When creating a named volume with `container volume create`, pass the `--opt size=<value>` flag to enforce capacity limits. For example, `--opt size=5g` creates a 5-gigabyte volume. You can also specify filesystem-specific options like `--opt journal=ordered` for ext4 volumes.