# How to Mount Host Directories into Containers on macOS with the Container CLI

> Learn how to mount host directories into containers on macOS using the container CLI. Effortlessly share files between your host and containers with simple flags.

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

---

**Use the `--volume <host-path>:<container-path>` or `--mount source=<host-path>,target=<container-path>` flags with `container run` to share macOS host directories with containers running inside the lightweight virtual machine.**

The `container` CLI from Apple's open-source [apple/container](https://github.com/apple/container) repository executes containers within a lightweight macOS virtual machine. To mount host directories into containers on macOS, you configure bind mounts using either the `--volume` or `--mount` flags, which leverage the macOS Virtualization framework to establish shared folders between the host and the VM.

## Understanding Bind Mounts in the Container Architecture

Unlike native Linux container runtimes, the `container` CLI runs each container inside a lightweight macOS VM. When you mount host directories into containers on macOS, the CLI performs a two-step binding process:

1. **Host to VM**: The macOS Virtualization framework creates a shared folder between the macOS host and the VM.
2. **VM to Container**: The VM's init process (`vminit`) forwards the shared folder to the container's mount namespace, presenting it as a standard Linux directory at your specified target path.

By default, these mounts are read-write (`rw`). You can modify this behavior using the `readonly` option with the `--mount` flag.

## Using the `--volume` Flag

The `--volume` flag provides the simplest syntax for bind mounts. According to [`docs/command-reference.md`](https://github.com/apple/container/blob/main/docs/command-reference.md), it accepts a colon-separated string mapping the host path to the container path.

**Syntax:**

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

```

**Example:**

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

```

Both paths must be absolute. Inside the container, files appear with the same contents as on the host, though typically owned by `root`.

## Using the `--mount` Flag

The `--mount` flag offers a more verbose, key-value syntax useful when you need additional options like `readonly`. As documented in [`docs/how-to.md`](https://github.com/apple/container/blob/main/docs/how-to.md), the syntax follows:

```bash
--mount source=<host-path>,target=<container-path>[,readonly]

```

**Equivalent Example:**

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

```

### Creating Read-Only Mounts

To prevent the container from modifying host files, append the `readonly` parameter:

```bash
container run \
  --mount source=${HOME}/Desktop/assets,target=/content/assets,readonly \
  docker.io/python:alpine \
  touch /content/assets/newfile

```

This command fails with "Read-only file system", protecting your host directory from container writes while still allowing the host to modify files.

## Real-World Development Examples

### Live Development with Node.js

For development workflows, mount your current working directory to see changes instantly:

```bash
container run \
  --volume "${PWD}:/app" \
  -w /app \
  node:18-alpine \
  npm start

```

Changes made to files in `${PWD}` on your Mac are immediately visible to the Node process inside the container.

### Multiple Mount Points

You can specify multiple `--volume` or `--mount` flags in a single command:

```bash
container run \
  --volume "${HOME}/data:/data" \
  --volume "${PWD}/config:/etc/app" \
  --mount source=${HOME}/logs,target=/var/log,readonly \
  myapp:latest

```

Remember that mounts are scoped to the specific container process; other containers do not see these mounts unless you repeat the flags.

## Under the Hood: VM Mount Propagation

The implementation relies on two key services within the `container` codebase:

- **[`Sources/Services/ContainerAPIService/Server/Volumes/VolumesService.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Server/Volumes/VolumesService.swift)**: Handles the server-side creation of shared folders and forwards them to the container.
- **[`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift)**: Manages the low-level VM mount configuration.

When you execute `container run` with a volume flag, [`VolumesService.swift`](https://github.com/apple/container/blob/main/VolumesService.swift) coordinates with the macOS Virtualization framework to establish the shared folder. The VM then exposes this folder to the container's root filesystem at the specified target path, making the host directory available as a normal Linux directory inside the container.

## Summary

- Use `--volume <src>:<dst>` for simple bind mounts or `--mount source=<src>,target=<dst>` for advanced options like `readonly`.
- Both host and container paths must be absolute paths.
- Mounts use the macOS Virtualization framework to create shared folders between the host and the lightweight VM.
- By default, mounts are read-write; add `readonly` to the `--mount` flag to restrict container modifications.
- Each mount is scoped to the specific container process and must be specified again for other containers.

## Frequently Asked Questions

### Do I need to use absolute paths when mounting directories?

Yes. Both the host path and the container path must be absolute paths. For example, use `${HOME}/Desktop/assets` or `/Users/username/Desktop/assets` rather than relative paths like `./assets`. Relative paths are not supported by the `container` CLI.

### Why does my container see files owned by root?

When you mount host directories into containers on macOS, the files appear inside the container with `root` ownership. This occurs because the container runtime inside the VM presents the shared folder with standard Linux permissions, and the container process typically runs as root. The file contents remain identical to the host, but ownership appears as root within the container namespace.

### Can I mount multiple directories in a single command?

Yes. You can specify multiple `--volume` or `--mount` flags in a single `container run` command. Each flag creates a separate bind mount, allowing you to mount source code, data directories, and configuration files simultaneously. Each mount is independent and scoped only to that container instance.

### Is there a performance penalty for bind mounts on macOS?

Bind mounts on macOS involve the Virtualization framework's shared folder mechanism, which adds a layer compared to native Linux bind mounts. However, for most development workflows, the performance is sufficient for code editing, asset serving, and logging. The overhead primarily affects I/O-intensive operations compared to running natively on Linux.