Volume Mounts
Share files between the host and machine using volume mounts.
Basic Mount
TypeScriptconst machine = await Machine.create({
name: 'with-mounts',
mounts: [
{ source: '/host/code', target: '/workspace' }
]
});
// Access mounted files
const result = await machine.exec(['cat', '/workspace/script.py']);
console.log(result.stdout); Python from smolvm import Machine, MachineConfig, MountSpec
config = MachineConfig(
name="with-mounts",
mounts=[
MountSpec(source="/host/code", target="/workspace")
]
)
async with Machine(config) as machine:
await machine.start()
result = await machine.exec(["cat", "/workspace/script.py"])
print(result.stdout) Read-Only Mounts
Mount directories as read-only for safety:
TypeScriptconst machine = await Machine.create({
name: 'readonly-mount',
mounts: [
{ source: '/host/data', target: '/data', readonly: true }
]
});
// Reading works
const result = await machine.exec(['cat', '/data/config.json']);
// Writing fails
const writeResult = await machine.exec(['touch', '/data/newfile']);
// writeResult.exitCode !== 0 Python config = MachineConfig(
name="readonly-mount",
mounts=[
MountSpec(source="/host/data", target="/data", readonly=True)
]
) Multiple Mounts
TypeScriptconst machine = await Machine.create({
name: 'multi-mount',
mounts: [
{ source: '/host/code', target: '/workspace' },
{ source: '/host/data', target: '/data', readonly: true },
{ source: '/host/output', target: '/output' }
]
}); Python config = MachineConfig(
name="multi-mount",
mounts=[
MountSpec(source="/host/code", target="/workspace"),
MountSpec(source="/host/data", target="/data", readonly=True),
MountSpec(source="/host/output", target="/output"),
]
) Writing Files
Write output from machine to host:
TypeScriptconst machine = await Machine.create({
name: 'writer',
mounts: [
{ source: '/tmp/machine-output', target: '/output' }
]
});
// Run computation and write result
await machine.run(
'python:3.12-alpine',
['python', '-c', `
import json
result = {"answer": 42}
with open("/output/result.json", "w") as f:
json.dump(result, f)
`]
);
// Result is now at /tmp/machine-output/result.json on the host Python config = MachineConfig(
name="writer",
mounts=[
MountSpec(source="/tmp/machine-output", target="/output")
]
)
async with Machine(config) as machine:
await machine.start()
await machine.run(
"python:3.12-alpine",
["python", "-c", """
import json
result = {"answer": 42}
with open("/output/result.json", "w") as f:
json.dump(result, f)
"""]
)
# Result is now at /tmp/machine-output/result.json Mount Path Guidelines
Use top-level paths. Avoid paths that overlap with system directories inside the container image.
Good paths:
/workspace— default persistent workspace; mounting here replaces it with your host directory/code/data/output
Avoid:
/var/data— conflicts with system directories inside the container/home/user/code— may conflict with the container image’s home directory
`/workspace` and host mounts
Every image-based machine exposes `/workspace` backed by the VM's storage disk (persists across exec sessions and stop/start). Mounting a host directory at `/workspace` takes priority — your host directory is used instead of the storage-disk workspace. Any other mount target leaves `/workspace` intact.Mount Permissions
The machine runs as root by default. Files created in mounted directories will be owned by root on the host.
To change ownership after execution:
# On the host, after machine execution
sudo chown -R $USER:$USER /tmp/machine-output Or create files with specific permissions in the machine:
await machine.exec([
"sh", "-c",
"echo 'content' > /output/file.txt && chmod 666 /output/file.txt"
])