# How to Mount a Host Directory into a Container with Apple Container

> Mount a host directory into an Apple Container with `container run --volume` or `--mount`. Easily share data between macOS and your Linux container filesystem.

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

---

**Mount a host directory into a container using `container run --volume <hostPath>:<containerPath>` for concise bind-mounts or `--mount type=bind,source=<hostPath>,target=<containerPath>` for explicit control, allowing data sharing between macOS and the Linux container filesystem.**

The `apple/container` open-source project enables seamless data sharing by forwarding macOS host paths through a lightweight VM into the container namespace. This bind-mount capability eliminates the need to copy files, letting you edit assets on your Mac and immediately access them inside the running container. Whether you need quick directory sharing or fine-grained permission control, the tool provides two distinct CLI flags to handle host-to-container file mapping.

## Using the --volume Flag for Quick Bind-Mounts

The `--volume` (or `-v`) flag offers the fastest way to mount a host directory into a container using a simple colon-separated syntax.

### Syntax and Parsing

The pattern requires an absolute host path and a container destination: `--volume <hostPath>:<containerPath>`. When you execute a command like `container run --volume ${HOME}/Desktop/assets:/content/assets <image>`, the CLI parses this string into a `Mount` struct that is passed directly to the container runtime. This parsing logic is validated in the integration test suite at [`Tests/IntegrationTests/Run/TestCLIRunCommand.swift`](https://github.com/apple/container/blob/main/Tests/IntegrationTests/Run/TestCLIRunCommand.swift) (line 344), demonstrating how the flag propagates from user input to the internal runtime API.

### Permission Suffixes

By default, mounted host directories are accessed read-only. You can explicitly control permissions by appending suffixes to the mount string:

- **`:ro`** – Explicit read-only (default behavior)
- **`:rw`** – Read-write access allowing modifications from within the container

For example, to allow the container to write changes back to your Desktop folder, use `--volume "${HOME}/Desktop/assets:/content/assets:rw"`.

## Using the --mount Flag for Explicit Control

When you need clearer semantics or additional mount options, the `--mount` flag provides a comma-separated key-value syntax that mirrors Docker's mount specification.

### Detailed Key-Value Configuration

The `--mount` format explicitly declares parameters: `--mount type=bind,source=<hostPath>,target=<containerPath>[,readonly]`. As documented in [`docs/how-to.md`](https://github.com/apple/container/blob/main/docs/how-to.md) (lines 54-60), this approach eliminates ambiguity by labeling each component (source vs. target) and supports the `readonly` keyword for explicit permission locking.

For instance, to mount assets as read-only using explicit syntax:

```bash
container run --rm \
    --mount type=bind,source=${HOME}/Desktop/assets,target=/content/assets,readonly \
    docker.io/python:alpine \
    ls -l /content/assets

```

The definitive specifications for both flags are outlined in [`docs/command-reference.md`](https://github.com/apple/container/blob/main/docs/command-reference.md) (lines 60-76), which defines the accepted parameters and validation rules used by the CLI.

## Practical Code Examples

These commands demonstrate mounting a host directory into a container using both available syntaxes:

```bash

# 1️⃣ Simple bind‑mount using --volume (read‑only by default)

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

```

```bash

# 2️⃣ Bind‑mount with explicit read‑write permission

container run --rm \
    --volume "${HOME}/Desktop/assets:/content/assets:rw" \
    docker.io/python:alpine \
    cat /content/assets/link.svg

```

```bash

# 3️⃣ Using the more flexible --mount syntax

container run --rm \
    --mount type=bind,source=${HOME}/Desktop/assets,target=/content/assets,readonly \
    docker.io/python:alpine \
    ls -l /content/assets

```

*Ensure the host directory exists before running these commands; replace `${HOME}/Desktop/assets` with your target path.*

## How Bind Mounts Work Under the Hood

Both `--volume` and `--mount` flags ultimately create bind-mounts within the lightweight VM that backs the container. According to the technical overview in [`docs/how-to.md`](https://github.com/apple/container/blob/main/docs/how-to.md) (lines 36-43), the `container-runtime-linux` component forwards the host macOS path into the VM, then attaches that directory to the container's namespace. This architecture allows the Linux container to access macOS filesystems with native performance characteristics while maintaining security isolation through the virtualization layer.

## Summary

- **Use `--volume`** for quick, concise syntax when you need immediate bind-mounts with simple permission controls (`:rw` or `:ro`).
- **Use `--mount`** when you require explicit parameter declaration and clearer readability, especially in scripts or automation.
- Both methods pass through the `Mount` struct defined in the CLI and are processed by `container-runtime-linux` to bridge the host VM and container namespace.
- Default permissions are read-only; explicitly add `:rw` or omit `readonly` to allow write access.
- Reference [`Tests/IntegrationTests/Run/TestCLIRunCommand.swift`](https://github.com/apple/container/blob/main/Tests/IntegrationTests/Run/TestCLIRunCommand.swift) for implementation details on how the CLI parses these flags into runtime calls.

## Frequently Asked Questions

### What is the difference between --volume and --mount in Apple Container?

The `--volume` flag uses a concise colon-separated syntax (`host:container[:mode]`) optimized for quick command-line usage, while `--mount` employs an explicit comma-separated key-value format (`type=bind,source=...,target=...`) that provides clearer parameter semantics and self-documenting commands. Both create identical bind-mounts in the underlying VM, but `--mount` prevents accidental order swaps between source and target paths.

### Are host directories mounted read-only by default?

Yes, when using `--volume`, host directories are mounted read-only unless you explicitly append the `:rw` suffix. Similarly, with `--mount`, you must deliberately omit the `readonly` keyword to allow write access from within the container. This default protects host data from accidental container-side modifications.

### Can I mount individual files or only directories?

While the examples focus on directories, you can mount individual files using the same syntax. Specify the file path as the source and the desired file location in the container as the target: `--volume "${HOME}/config.txt:/app/config.txt"` or `--mount type=bind,source=${HOME}/config.txt,target=/app/config.txt".

### How does the container runtime access macOS host paths?

The `container-runtime-linux` component bridges the gap by forwarding the macOS host path into the lightweight Linux VM that powers the container, then performing a bind-mount operation to attach that path to the container's mount namespace. This process is transparent to the container, which sees the host files as standard Linux filesystem entries.