# How do I run Docker Compose inside an AI agent's sandbox?

> Use a Sanbox Docker Computer: a microVM with its own Docker Engine, Compose and Buildx. Allow your registries, copy the project in, and run docker compose through sanbox exec.

- Source: Sanbox knowledge base, by Sanlabs GmbH
- URL: https://sanbox.cloud/kb/parallel-work/docker-compose-inside-an-agent-computer/
- Type: how-to
- Section: Parallel and background work
- Language: en
- Published: 2026-11-06
- Updated: 2026-11-06

Give the agent a whole machine with its own Docker Engine instead of a share of yours. A Sanbox Docker Computer is a Firecracker microVM with Docker Engine, Buildx and Compose already set up: you allow the registries your images come from, copy the project in with `sanbox cp`, and run `docker compose` with `sanbox exec`. The common alternative, mounting your host's Docker socket into the agent's container, hands it control of your Docker daemon, and Docker's own docs say only trusted users should have that.

## Run this with your agent

```text
Read https://sanbox.cloud/kb/parallel-work/docker-compose-inside-an-agent-computer.md and follow it to run my Compose stack in a Docker Computer.
If the Sanbox CLI is missing, install it with `npm install -g @sanlabs/sanbox-cli@latest`
and sign in with `sanbox login`. Show me each command before you create, stop or delete a Computer.
```

## What's in a Docker Computer?

- **Docker Engine, Buildx and Compose** inside the run's own microVM. It doesn't share Docker with anyone, and containers, builds and Compose stacks need no special privileges, because the run is the security boundary.
- **A small Debian bookworm-slim image** with git, curl, jq, zip and unzip, openssh and zellij. There is no Node and no Python preinstalled.
- **No agent and no model.** It takes no task and has no chat. Your coding agent, CI job or application drives it with `sanbox exec`, `sanbox cp`, the console terminal or SSH.
- **Defaults** of 2 vCPUs, 8 GB of memory and an 8 GB disk.
- **The `sanbox` user** runs commands and can use `docker` without `sudo`.

`sanbox exec`, `sanbox cp` and the `docker-computer` type need CLI 0.0.19 or later.

## Which hosts does the network policy need?

A new Docker Computer can't reach the internet. Image pulls go through the run's egress proxy, so list every registry you pull from, on port 443:

- **Docker Hub:** `registry-1.docker.io`, `auth.docker.io`, and both layer CDNs, `production.cloudfront.docker.com` and `production.cloudflare.docker.com`
- **GitHub Container Registry:** `ghcr.io` and `pkg-containers.githubusercontent.com`
- **Package mirrors your builds use**, such as `deb.debian.org`, `pypi.org` or `registry.npmjs.org`, each need their own rule for the ports they use

Save this as `registries.json` for Docker Hub:

```json
{
  "default_action": "deny",
  "rules": [
    { "destination": "registry-1.docker.io", "ports": [{ "from": 443, "to": 443 }] },
    { "destination": "auth.docker.io", "ports": [{ "from": 443, "to": 443 }] },
    { "destination": "production.cloudfront.docker.com", "ports": [{ "from": 443, "to": 443 }] },
    { "destination": "production.cloudflare.docker.com", "ports": [{ "from": 443, "to": 443 }] }
  ]
}
```

A pull blocked by the policy names the host it couldn't reach, so add hosts as errors show them. A template can hold at most 16 rules.

## Steps

### 1. Create the template

```bash
sanbox templates create --name "Compose stack" --type docker-computer \
  --network-policy registries.json --json
```

### 2. Start a Docker Computer

```bash
sanbox run --template <template-id> --json
sanbox runs get <run-id> --json
```

Wait until the run is `running`.

### 3. Copy the project in

```bash
sanbox cp ./app <run-id>:/workspace
```

This creates `/workspace/app`. Uploads must finish within about five minutes, so send source code, not build output.

### 4. Start the stack and run the tests

```bash
sanbox exec <run-id> --cwd /workspace/app -- docker compose up -d
sanbox exec <run-id> --cwd /workspace/app -- docker compose exec -T api pytest
```

`sanbox exec` streams output and exits with the command's exit code, so your agent or CI job sees whether the tests passed.

### 5. Run long jobs detached

A dropped connection doesn't stop a command. For jobs longer than the default 3,600-second timeout, raise it (up to 86,400 seconds) and detach:

```bash
sanbox exec <run-id> --detach --timeout 86400 --request-key <key> --json -- ./long-job.sh
sanbox commands logs <run-id> <command-id> --follow
```

Reuse the same `--request-key` when you retry, so a lost response can't start the job twice. Each command keeps its newest 8 MiB of output, and the run forgets commands when it stops.

### 6. Copy results out

```bash
sanbox cp <run-id>:/workspace/app/reports .
```

This creates `./reports` on your machine.

## Why can't my services reach each other over HTTP?

Containers reach the network only through the run's proxy at `http://169.254.77.1:3128`, and Docker passes it to containers and builds automatically. HTTP calls between Compose services go to that proxy too, unless the service names are in `NO_PROXY`. Add them to each service that makes such calls:

```yaml
services:
  api:
    build: .
    restart: unless-stopped
    environment:
      NO_PROXY: "worker,localhost,127.0.0.1"
  worker:
    build: ./worker
    restart: unless-stopped
```

## Does the stack survive a stop?

Images, build caches and volumes live on the Computer's disk, so stop, resume, fork, snapshots and warm pools keep them.

- **Containers come back after a resume only with a restart policy**, such as `restart: unless-stopped`. Compose's docs define it as restarting regardless of exit code, unless the service was stopped or removed.
- **Stop saves everything written before it**, then gives containers up to 15 seconds to exit before they're killed.
- **Registry logins are held in memory for the current boot.** Run `docker login` again after a resume. Logins aren't saved in snapshots.

The disk holds images, volumes and `/workspace`. Docker Computers default to 8 GB, which is also the most `sanbox templates storage set <template-id> --gb <1-8>` allows. Larger disks are available on request.

## Can I use Testcontainers?

Testcontainers starts containers by talking to the Docker daemon, so a suite that uses it can run inside the Docker Computer, next to its Docker Engine. Three things to plan for:

- **Install your test runtime first.** The image has no Node, Python or Java.
- **Allow Docker Hub.** Testcontainers pulls its own helper images, including its Ryuk cleanup container (`testcontainers/ryuk`), as well as the images your tests ask for.
- **Proxy settings reach containers through the Docker client's configuration.** Docker's docs describe that file as client configuration, so containers that a library creates directly through the Docker API may not get it. If such a container needs the internet, set `HTTP_PROXY` and `HTTPS_PROXY` to `http://169.254.77.1:3128` on it yourself.

## Snapshot it

Pull images and build once, then reuse the result. Stop the prepared Computer and capture it (this needs an organisation admin or owner):

```bash
sanbox runs stop <run-id> --wait --json
sanbox snapshots create --run <run-id> --name compose-ready
sanbox pools create --snapshot compose-ready --name compose-pool --size 2
sanbox run --snapshot compose-ready --json
```

The snapshot keeps images, containers and data. Containers kept by a snapshot or warm pool keep their network access, because the proxy address is the same in every run.

## What this doesn't do

- **No agent inside.** A Docker Computer is just a computer. Drive it from your own agent or pipeline.
- **No public ports.** Services are reachable only through authenticated port connections, for HTTP and SSE. See [how to preview a dev server](https://sanbox.cloud/kb/parallel-work/preview-your-agents-dev-server/).
- **No GPUs.**

## Related

- [How do I preview the dev server my agent is running?](https://sanbox.cloud/kb/parallel-work/preview-your-agents-dev-server/)
- [Container, microVM or VM: which isolation for coding agents?](https://sanbox.cloud/kb/agent-computers/container-microvm-or-vm-for-coding-agents/)
- [Why can't my AI agent reach a website or package registry?](https://sanbox.cloud/kb/errors/why-cant-my-agent-reach-a-website/)
- [How do I make agent computers start instantly?](https://sanbox.cloud/kb/build/warm-pools-and-snapshot-templates/)
- [Docker sandboxes vs a persistent cloud computer](https://sanbox.cloud/compare/docker-sandboxes-vs-a-persistent-computer/)

## Sources

- Docker, [Docker Engine security: Docker daemon attack surface](https://docs.docker.com/engine/security/), checked 2026-11-06
- Docker, [Use a proxy server with the Docker CLI](https://docs.docker.com/engine/cli/proxy/), checked 2026-11-06
- Docker, [Compose file reference: services, restart](https://docs.docker.com/reference/compose-file/services/), checked 2026-11-06
- Testcontainers, [Custom configuration (Ryuk image)](https://java.testcontainers.org/features/configuration/), checked 2026-11-06

## Next step

Talk to us at sales@sanlabs.ai. Sanlabs' forward-deployed engineers build agent use cases with your team, with experience in aviation, pharmaceuticals, supply chain and logistics, and internal admin workflows. How we work: https://sanbox.cloud/kb/teams/forward-deployed-engineering.md

Existing customers can use Sanbox from a coding agent: install the CLI with `npm install -g @sanlabs/sanbox-cli@latest`, sign in with `sanbox login`, then run `sanbox skill` for the full agent guide.
