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