---
title: The machine
description: Sizes, the Ubuntu 24.04 image every sandbox starts from, the default user, the desktop, and the helpers installed in every sandbox.
---

Every sandbox is a virtual machine that boots the same Ubuntu 24.04 image, or a [template](/sandboxes/templates/) made from it. It is set up for development and for AI agents: a normal Linux server plus a desktop with a browser.

## Sizes

Choose the size when you create a sandbox (`--size`, default `default`); a fork keeps the size of its source.

| Size | vCPU | RAM | Disk | List price |
| --- | --- | --- | --- | --- |
| `small` | 2 | 4 GiB | 20 GiB | €0.02 per hour |
| `default` | 4 | 8 GiB | 50 GiB | €0.04 per hour |
| `large` | 8 | 16 GiB | 100 GiB | €0.08 per hour |
| `xlarge` | 16 | 32 GiB | 200 GiB | €0.16 per hour |

Only running time is billed, per second. The guest sees slightly less memory than the size's RAM, because its kernel reserves part of it. A sandbox made from a template needs a size whose disk is at least as large as the template's.

## The user

Commands run as `user` (uid 1000, home `/home/user`, shell bash) unless you ask for root with `pols exec --root`. `user` has passwordless `sudo` and is in the `docker` group, so Docker works without `sudo`. The account has no password; SSH accepts keys only.

## What is installed

| Area | Contents |
| --- | --- |
| System | Ubuntu 24.04 with systemd, UTC time zone, `C.UTF-8` locale |
| Tools | git, git-lfs, curl, wget, jq, zip and unzip, xz, zstd, build-essential, cmake, pkg-config, ripgrep, fd, sqlite3, htop, tmux, vim, nano, strace, lsof, dnsutils, netcat |
| Containers | Docker Engine with the buildx and compose plugins, started at boot |
| Languages | Python 3 with pip, venv and pipx; Node.js with npm and corepack; Go |
| Browser | Google Chrome stable |
| Media | ffmpeg |
| Agents | Claude Code (`claude`) and Codex (`codex`) |
| Desktop | a 1920x1080 X11 desktop (TigerVNC, openbox) with xterm |

The exact versions of everything pinned in the image are listed in `/etc/pols/image-manifest.json` inside the sandbox.

A few things behave differently from a stock Ubuntu install:

- **apt**: the package lists are empty in a new sandbox. Run `sudo apt-get update` before installing packages. Automatic background updates are off, so they never hold the package lock while you or an agent work.
- **Python**: the system pip is "externally managed" (PEP 668). Use a virtual environment or `pipx`.
- **Agent CLIs**: auto-update is turned off for Claude Code and Codex. No API keys are baked into the image; pass yours with the [vault](/sandboxes/vault/) or `--env`.

## The desktop

Every running sandbox has an X11 desktop on display `:1` at 1920x1080 with Google Chrome. Login shells have `DISPLAY=:1` set; for other commands, set it yourself. You can watch and use the desktop in your browser with [`pols desktop`](/access/desktop/), and agents can drive it through [computer use](/agents/computer-use/).

The desktop's VNC server and Chrome's debugging port listen only inside the VM. They are reached through the control plane, never over the network.

## Helpers

The image includes small commands for working with the desktop from inside the sandbox:

| Command | Does |
| --- | --- |
| `pols-record start [--output FILE]`, `pols-record stop`, `pols-record status` | record the desktop to an MP4 file (30 fps), by default under `~/recordings/` |
| `pols-desktop status` | check that the desktop services are running |
| `pols-computer` | take screenshots and send mouse and keyboard input on the desktop |
| `pols-browser` | start Chrome with its DevTools endpoint |

The control plane uses `pols-computer` and `pols-browser` for [computer use](/agents/computer-use/); you normally use the API for that rather than calling them yourself.

## Identity of copies

Forks and sandboxes made from templates start from a copy of another disk. On their first boot they get a new machine ID and new SSH host keys, so two copies never share an identity.
