> ## 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.

# Docker and Compose

> Build images and run Docker containers or Compose services inside a persistent VM

Enable the Docker daemon when creating your VM. Prepared VM images already include Docker, Compose, and Buildx:

```bash theme={null}
beam vm new docker-dev --docker-enabled --protected-port 7681
beam vm exec docker-dev -- docker version
beam vm exec docker-dev -- docker compose version
beam vm exec docker-dev -- docker run --rm hello-world
```

Docker's images, build cache, container layers, and named volumes are stored in the VM root and survive stop/start. Use restart policies for containers that should start on a cold boot. Pause/resume preserves their running state with the rest of the guest.

## Build and run from the SDK

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

with VM.connect("docker-dev") as vm:
    with vm.keep_alive():
        vm.fs.create_directory("/workspace/app")
        vm.fs.write_text(
            "/workspace/app/Dockerfile",
            'FROM alpine:3.20\nCMD ["echo", "hello"]\n',
        )
        build = vm.docker.build(tag="example:latest", context="/workspace/app")
        for line in build.logs():
            print(line, end="")
        if not build.wait():
            raise RuntimeError(build.stderr)
        run = vm.docker.run("example:latest", remove=True)
        run.wait()
        print(run.stdout)
        print(run.stderr)
```

Docker operations return `DockerResult` handles with `wait()`, `success`, `stdout`, `stderr`, and combined `logs()`. Unlike `process.logs`, Docker's `logs()` is a method. Build progress often appears on stderr.

The SDK Docker helpers use the VM's network namespace. Publish the service's actual listening port with `vm.expose()`; SDK host-port remapping is unsupported. Direct commands issued through SSH or `vm.process.exec("docker", ...)` use normal guest Docker behavior and need their own Docker networking configuration.

## Compose from the CLI

Upload your project, then run Compose inside the VM:

```bash theme={null}
beam vm sync docker-dev ./project
beam vm exec docker-dev -- docker compose -f compose.yaml up -d --build
beam vm exec docker-dev -- docker compose -f compose.yaml ps
beam vm exec docker-dev -- docker compose -f compose.yaml logs --tail 100
beam vm expose docker-dev 8000 --protected
```

For direct Compose commands, configure `ports` or host networking in your Compose file so the application is reachable on the VM's published port.

## Compose from the SDK

The SDK Compose helpers apply the shared host-network/PID configuration and reuse the same configuration for subsequent stack operations:

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

with VM.connect("docker-dev") as vm:
    with vm.keep_alive():
        vm.fs.upload_file("compose.yaml", "/workspace/compose.yaml")
        stack = vm.docker.compose_up(file="compose.yaml", cwd="/workspace", build=True)
        print(stack.ps())
        print(stack.logs())
        print(vm.expose(8000, protected=True))
        # When finished with these services:
        stack.stop()
```

Upload any Dockerfiles and source referenced by Compose's build contexts before starting the stack. Services using the SDK helpers must listen on distinct guest ports. See [Docker APIs](/v2/sandbox/docker) for image/container operations, and use `vm.aio.docker` for async calls.

For long builds on an idle-limited VM, hold `vm.keep_alive()` or disable the TTL. For daemon diagnostics, use `beam vm logs docker-dev --unit docker.service`.


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