Skip to main content

Docker

Template

Use the official installation script from get.docker.com. The hello-world container run validates the installation.
// template.ts
import { Template } from 'e2b'

export const template = Template()
  .fromUbuntuImage('25.04')
  .runCmd('curl -fsSL https://get.docker.com | sudo sh')
  .runCmd('sudo docker run --rm hello-world')

Build

We recommend at least 2 CPUs and 2 GB of RAM for running Docker containers. With lower RAM, your sandbox might run out of memory.
// build.ts
import { Template, defaultBuildLogger } from 'e2b'
import { template as dockerTemplate } from './template'

Template.build(dockerTemplate, 'docker', {
  cpuCount: 2,
  memoryMB: 2048,
  onBuildLogs: defaultBuildLogger(),
})

Run

Run an Alpine container that prints a hello message.
// sandbox.ts
import { Sandbox } from 'e2b'

const sbx = await Sandbox.create('docker')

const result = await sbx.commands.run('sudo docker run --rm alpine echo "Hello from Alpine!"')
console.log(result.stdout)

await sbx.kill()

Docker Compose

This example installs Docker and Docker Compose, then validates the setup with a Compose version check and a sample Compose run.
Run Docker and Docker Compose commands as root in this setup. The Docker daemon socket is not accessible to the default user account.

Template

Create a new file named template-compose.ts (or template_compose.py).
// template-compose.ts
import { Template } from 'e2b'

export const composeTemplate = Template()
  .fromUbuntuImage('24.04')
  .runCmd([
    'set -euxo pipefail',
    'sudo apt-get update',
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y docker.io',
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y docker-compose-plugin || true',
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y docker-compose-v2 || true',
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y docker-compose || true',
    'sudo docker compose version || sudo docker-compose --version',
  ])
Expected result: you now have a local template-compose.ts or template_compose.py file.

Build

// build-compose.ts
import { Template, defaultBuildLogger } from 'e2b'
import { composeTemplate } from './template-compose'

Template.build(composeTemplate, 'docker-compose', {
  cpuCount: 2,
  memoryMB: 2048,
  onBuildLogs: defaultBuildLogger(),
})
Expected output (example):
BuildInfo(... name='docker-compose', alias='docker-compose', tags=['default'])

Run

// sandbox-compose.ts
import { Sandbox } from 'e2b'

const sbx = await Sandbox.create('docker-compose')

await sbx.commands.run('mkdir -p /tmp/docker-compose-test', { user: 'root' })
await sbx.files.write('/tmp/docker-compose-test/compose.yaml', [
  'services:',
  '  hello:',
  '    image: busybox:1.36',
  '    command: ["sh", "-lc", "echo docker-compose-ok"]',
  '',
].join('\n'))

const result = await sbx.commands.run(`
set -euxo pipefail
cd /tmp/docker-compose-test

if docker compose version >/dev/null 2>&1; then
  docker compose up --abort-on-container-exit --remove-orphans
  docker compose down --remove-orphans -v
  echo "Docker Compose ran successfully"
elif docker-compose --version >/dev/null 2>&1; then
  docker-compose up --abort-on-container-exit --remove-orphans
  docker-compose down --remove-orphans -v
  echo "Docker Compose ran successfully"
else
  echo "No compose command available"
  exit 127
fi
`, { user: 'root' })

console.log(result.stdout)
await sbx.kill()
Expected output (example):
hello_1  | docker-compose-ok
Docker Compose ran successfully