> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beam.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> Choose VM resources, build images, and configure environment variables and storage

## CPU, memory, and root disk

```bash theme={null}
beam vm new devbox --cpu 4 --memory 8192 --disk-size 100Gi \
  --protected-port 7681
```

```python theme={null}
from beam import VM

vm = VM(
    "python-devbox",
    cpu=4,
    memory=8192,
    disk_size="100Gi",
    protected_ports=[7681],
).create()
```

| Setting | CLI | Python | Default |
| - | - | - | - |
| CPU cores | `--cpu 4` | `cpu=4` | 4; minimum 0.1 |
| Memory in MiB | `--memory 8192` | `memory=8192` | 8192; minimum 256 |
| Writable root capacity | `--disk-size 50Gi` | `disk_size="50Gi"` | 50 GiB; minimum 1 GiB, maximum 100 GiB |
| Browser desktop | `--desktop` | `desktop=True` | Disabled; requires at least 2048 MiB RAM |
| Docker daemon | `--docker-enabled` | `docker_enabled=True` | Disabled |
| SSH | Omit `--no-ssh` | `ssh=True` | Enabled for a new VM |
| Idle TTL in seconds | `--ttl 300` | `ttl=300` | Disabled |
| Automatic resume | `--auto-resume` | `auto_resume=True` | Disabled |

VMs are CPU-only. Resource availability depends on the microVM serverless pool. You normally do not need `--pool`; use it to select a CPU microVM pool you have access to.

Choose CPU, memory, root disk size, and image when creating the VM. `beam vm update` changes idle behavior and metadata, not the machine's allocation or root disk capacity. See [storage](/v2/vm/storage) for what `df -h /` reports.

### Names and IDs

Names are unique within a workspace. A name must begin with a lowercase letter and contain at most 24 lowercase letters, digits, or hyphens. Omit the name for a generated name such as `calm-fox-5959d8`.

The VM also has an immutable ID such as `vm-0123456789abcdef`. Use its name or ID with `beam vm get`, `start`, `stop`, and other commands. A VM's current container ID may change when it restarts; use the VM identity when reconnecting.

## Base images

VM images require **Debian or Ubuntu**. Beam adds systemd, SSH, the browser terminal, and its VM boot services to registry images or the final stage of your Dockerfile. The default base image is `ubuntu:22.04`.

```bash theme={null}
beam vm new debian-dev --image debian:bookworm --protected-port 7681
```

The browser desktop currently requires **Ubuntu 22.04 (jammy)**. Use the default image for desktop VMs. Alpine and other distributions without the supported apt/systemd setup are not supported VM bases.

### Build a custom image

For example, create a `Dockerfile` that installs your tools:

```dockerfile Dockerfile theme={null}
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential git jq python3-venv \
    && rm -rf /var/lib/apt/lists/*
WORKDIR /workspace
```

Create a VM directly from the Dockerfile:

```bash theme={null}
beam vm new buildbox --dockerfile Dockerfile --build-context . \
  --protected-port 7681
```

Or build a reusable VM image first:

```bash theme={null}
beam vm image build . --file Dockerfile --json
# Use the image_id in the result:
beam vm new buildbox --image-id IMAGE_ID --protected-port 7681
```

Use `beam vm image build --desktop` when the image will provide a desktop. An `--image-id` must already include the VM services; Beam cannot append packages to an existing immutable image ID. Do not pass an arbitrary sandbox image ID and expect VM services to be added.

The Python SDK accepts an `Image`:

```python theme={null}
from beam import Image, VM

image = Image.from_dockerfile("Dockerfile", context_dir=".")
vm = VM("python-buildbox", image=image, protected_ports=[7681]).create()
```

Use [systemd units](/v2/vm/processes#systemd-services) to start services on VM boots. A VM boots systemd rather than using a Dockerfile's `CMD` as its application service.

## Environment variables and secrets

Pass ordinary configuration with repeatable `--env` flags. Pass existing [workspace secrets](/v2/environment/secrets) by name:

```bash theme={null}
beam vm new agentbox --env APP_ENV=development --env LOG_LEVEL=info \
  --secret OPENAI_API_KEY --protected-port 7681
```

```python theme={null}
from beam import VM

vm = VM(
    "python-agentbox",
    env={"APP_ENV": "development", "LOG_LEVEL": "info"},
    secrets=["OPENAI_API_KEY"],
    protected_ports=[7681],
).create()
```

Use `--build-secret NAME` for secrets needed during image building. Build secrets and runtime secrets are separate settings. Names beginning with `BEAM_VM_` or `BETA9_` are reserved.

## Additional storage

Every VM already has a durable root. Attach a separate named disk or shared workspace volume when your data needs an independent lifetime:

```bash theme={null}
beam vm new databox --disk project-data:/data:20Gi \
  --volume shared-datasets:/datasets --protected-port 7681
```

```python theme={null}
from beam import DurableDisk, VM, Volume

vm = VM(
    "python-databox",
    disks=[DurableDisk(name="project-data", mount_path="/data", size="20Gi")],
    volumes=[Volume(name="shared-datasets", mount_path="/datasets")],
    protected_ports=[7681],
).create()
```

Additional VM disks use the qcow driver and ext4. Disk names cannot begin with `vm-`, which is reserved for VM roots. Mount paths must be unique absolute paths, must not overlap, and cannot replace `/`, `/dev`, `/proc`, `/sys`, `/run`, or `/.beam`.

These mounts are separate from the root snapshot. Read [snapshot and fork boundaries](/v2/vm/storage#what-a-snapshot-includes) before using them in a reusable environment.

## Metadata and creation retries

Use metadata to label environments and filter the VM list:

```bash theme={null}
beam vm new devbox --metadata project=demo --metadata owner=engineering \
  --protected-port 7681
beam vm list --metadata project=demo
beam vm update devbox --metadata project=demo --metadata owner=platform
beam vm update devbox --clear-metadata
```

An update replaces the complete metadata map. Metadata is visible in management responses; keep credentials in secrets.

For creation retries, pass the same UUID as `--request-id`, or `request_id` in Python, with the same creation options. Reusing that request ID with a changed request is rejected. Reusing the same prepared Python `VM` object retains its request ID and prepared image, so a lost response can be retried without creating another VM.

When creating from a [template or snapshot](/v2/vm/storage), omitted configuration inherits the saved specification. Explicit settings override it. Choose one image source: registry image, image ID, Dockerfile, or template.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.