Skip to content

Volume Mounts

Share files between the host and machine using volume mounts.

Basic Mount

typescript
const 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:

typescript
const 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

typescript
const 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:

typescript
const 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

Important

Use top-level mount paths like /workspace or /code. Nested paths may conflict with container overlays.

Good paths:

  • /workspace
  • /code
  • /data
  • /output

Avoid:

  • /mnt/host/code - nested under /mnt
  • /var/data - conflicts with system directories
  • /home/user/code - may conflict with container user home

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:

bash
# On the host, after machine execution
sudo chown -R $USER:$USER /tmp/machine-output

Or create files with specific permissions in the machine:

python
await machine.exec([
    "sh", "-c",
    "echo 'content' > /output/file.txt && chmod 666 /output/file.txt"
])