How to Use Container Machine Home Directory Mounts (ro/rw) in Apple Container
The container machine command maps your macOS $HOME directory into a persistent Linux VM using the --home-mount flag, supporting rw (read-write), ro (read-only), or none modes to protect or expose host filesystem access.
The apple/container repository provides a container machine feature that creates persistent Linux VMs on macOS. When you initialize a container machine, the tool automatically handles home directory mounts through the MachineConfig.HomeMountOption setting, allowing you to control exactly how the guest VM interacts with your host files.
Understanding Home Mount Options
The home mount behavior is controlled by the home-mount option passed during machine creation or modification. According to Sources/ContainerPersistence/MachineConfig.swift, this configuration supports three distinct modes:
rw(default): The host home directory mounts read-write at/home/<user>(or/Users/<user>on macOS). Changes made inside the VM immediately reflect on the host filesystem.ro: The host home directory mounts read-only. The VM can read files, but any write attempts fail, protecting host data from accidental modification.none: No home directory mounts automatically. The VM sees a fresh empty$HOME, requiring you to bind-mount specific directories manually.
The default value is defined in MachineConfig.defaultHomeMount = .rw at lines 40-41 of MachineConfig.swift.
Implementation in Source Code
When a machine boots, MachinesService.swift (lines 365-672) passes the selected homeMountOption to the underlying virtualization framework. The system creates the appropriate bind-mount using options: [homeMountOption.rawValue], translating your CLI flag into low-level VM configuration.
The MachineConfig struct at lines 42-47 of Sources/ContainerPersistence/MachineConfig.swift defines the parsing logic and validation for these options, ensuring only valid mount modes are accepted.
Creating Machines with Home Directory Mounts
Create a Machine with Read-Only Home Access
To protect your host data, create a machine that mounts your home directory as read-only:
# Create a container machine named "dev-ro" with read-only home mount
container machine create alpine:latest \
--name dev-ro \
--home-mount ro
Verify Mount Permissions Inside the VM
Test whether the mount is actually read-only by attempting to write to $HOME:
# Open a shell and test write access
container machine run -n dev-ro -- bash -c '
echo "test" > "$HOME/test.txt" && echo "writable" || echo "read-only"
'
# Expected output: "read-only"
Default Read-Write Behavior
If you omit the --home-mount flag, the machine defaults to rw mode:
# Creates machine with read-write home mount (default)
container machine create ubuntu:latest --name dev-rw
Modifying Home Directory Mounts on Existing Machines
You can change the mount mode of an existing machine using the machine set command. According to the command reference at docs/command-reference.md (lines 1067-1086), this updates the stored MachineConfig but requires a restart to take effect.
Change to Read-Write
container machine set -n dev home-mount=rw
Remove Home Mount Entirely
container machine set -n dev home-mount=none
Apply Changes with Restart
After modifying the mount type, you must stop and restart the machine:
container machine stop dev
container machine run -n dev # Boots with new home-mount option
Adding Additional Read-Only Mounts
For directories outside your home folder, use the generic --mount flag with the readonly option. This syntax is documented in docs/command-reference.md (lines 60-74):
container run --mount type=bind,source=${HOME}/Documents,target=/mnt/docs,readonly \
docker.io/python:alpine ls -l /mnt/docs
This approach complements the home directory mount by providing fine-grained control over specific host paths without exposing your entire $HOME directory.
Summary
- Home mount options include
rw(default read-write),ro(read-only protection), andnone(no automatic mounting). - Configuration is stored in
MachineConfig.HomeMountOptionwithinSources/ContainerPersistence/MachineConfig.swiftand applied byMachinesService.swiftduring VM boot. - Creation: Use
--home-mount roor--home-mount rwwithcontainer machine create. - Modification: Use
container machine set -n <name> home-mount=<mode>followed by a stop/start cycle. - Additional mounts: Use the
--mountflag withreadonlyfor specific directories outside your home folder.
Frequently Asked Questions
What happens if I try to write to a read-only home mount?
The operation fails with a permission denied error. When --home-mount ro is set, the underlying virtualization framework mounts the host directory with read-only flags, preventing any write operations from the guest VM while still allowing full read access to your files.
Can I switch from read-write to read-only without recreating the machine?
Yes. Use container machine set -n <machine-name> home-mount=ro to update the configuration stored in MachineConfig. However, you must run container machine stop <name> followed by container machine run (or start) to apply the change, as the mount option is only processed during VM initialization.
Why would I use none instead of ro for the home mount?
The none option creates an isolated environment where the VM has a fresh, empty $HOME directory. This is useful when you want complete separation from host configuration files, need to test software in a clean home directory, or plan to manually bind-mount only specific project directories using the --mount flag instead of exposing your entire user folder.
Where does the container machine mount the home directory inside the VM?
The host home directory mounts at /home/<username> inside the Linux VM (or /Users/<username> on macOS hosts). This path corresponds to the standard $HOME environment variable within the guest, ensuring tools and shells behave as expected while respecting the read-only or read-write constraints you've configured.
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 →