How to Mount a Host Directory into a Container with Apple Container
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 (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 (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:
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 (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:
# 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
# 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
# 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 (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
--volumefor quick, concise syntax when you need immediate bind-mounts with simple permission controls (:rwor:ro). - Use
--mountwhen you require explicit parameter declaration and clearer readability, especially in scripts or automation. - Both methods pass through the
Mountstruct defined in the CLI and are processed bycontainer-runtime-linuxto bridge the host VM and container namespace. - Default permissions are read-only; explicitly add
:rwor omitreadonlyto allow write access. - Reference
Tests/IntegrationTests/Run/TestCLIRunCommand.swiftfor 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →