# Docker (/docs/template/examples/docker)

<!-- agent-signals: reading_time_min: 4 · est_tokens: 2654 · updated: 2026-07-30 -->
Related: [Next.js app](/docs/template/examples/nextjs.md), [Next.js app (Bun)](/docs/template/examples/nextjs-bun.md), [Expo app](/docs/template/examples/expo.md), [Desktop](/docs/template/examples/desktop.md), [Claude Code](/docs/template/examples/claude-code.md), [Internet access](/docs/network/internet-access.md)

## Docker [#docker]

### Template [#template]

Use the official installation script from [get.docker.com](https://get.docker.com). The `hello-world` container run validates the installation.

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```typescript  
      // template.ts
      import { Template } from 'e2b'

      export const template = Template()
        .fromUbuntuImage('24.04')
        .runCmd('curl -fsSL https://get.docker.com | sudo sh')
        .runCmd('sudo docker run --rm hello-world')
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python  
      # template.py
      from e2b import Template

      template = (
          Template()
          .from_ubuntu_image("24.04")
          .run_cmd("curl -fsSL https://get.docker.com | sudo sh")
          .run_cmd("sudo docker run --rm hello-world")
      )
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

### Build [#build]

We recommend at least 2 CPUs and 2 GB of RAM for running Docker containers. &#x2A;*With lower RAM, your sandbox might run out of memory.**

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```typescript  
      // build.ts
      import { Template, defaultBuildLogger } from 'e2b'
      import { template as dockerTemplate } from './template'

      Template.build(dockerTemplate, 'docker', {
        cpuCount: 2,
        memoryMB: 2048,
        onBuildLogs: defaultBuildLogger(),
      })
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python  
      # build.py
      from e2b import Template, default_build_logger
      from .template import template as dockerTemplate

      Template.build(dockerTemplate, 'docker',
          cpu_count=2,
          memory_mb=2048,
          on_build_logs=default_build_logger(),
      )
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

### Run [#run]

Run an Alpine container that prints a hello message.

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```typescript  
      // 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()
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python  
      # sandbox.py
      from e2b import Sandbox

      sbx = Sandbox.create('docker')

      result = sbx.commands.run('sudo docker run --rm alpine echo "Hello from Alpine!"')
      print(result.stdout)

      sbx.kill()
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

## Docker Compose [#docker-compose]

This example installs Docker and Docker Compose, then validates the setup with a Compose version check and a sample Compose run.

### Template [#template-1]

Create a new file named `template-compose.ts` (or `template_compose.py`).

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```typescript  
      // 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 usermod -aG docker user',
          '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',
        ])
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python  
      # template_compose.py
      from e2b import Template

      compose_template = (
          Template()
          .from_ubuntu_image("24.04")
          .run_cmd(
              [
                  "set -euxo pipefail",
                  "sudo apt-get update",
                  "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y docker.io",
                  "sudo usermod -aG docker user",
                  "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",
              ]
          )
      )
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

Expected result: you now have a local `template-compose.ts` or `template_compose.py` file.

### Build [#build-1]

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```typescript  
      // build-compose.ts
      import { Template, defaultBuildLogger } from 'e2b'
      import { composeTemplate } from './template-compose'

      Template.build(composeTemplate, 'docker-compose', {
        cpuCount: 2,
        memoryMB: 2048,
        onBuildLogs: defaultBuildLogger(),
      })
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python  
      # build_compose.py
      from e2b import Template, default_build_logger
      from template_compose import compose_template

      Template.build(compose_template, "docker-compose",
          cpu_count=2,
          memory_mb=2048,
          on_build_logs=default_build_logger(),
      )
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

Expected output (example):

```text
BuildInfo(... name='docker-compose', alias='docker-compose', tags=['default'])
```

### Run [#run-1]

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```typescript  
      // sandbox-compose.ts
      import { Sandbox } from 'e2b'

      const sbx = await Sandbox.create('docker-compose')

      await sbx.commands.run('mkdir -p /tmp/docker-compose-test')
      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
      `)

      console.log(result.stdout)
      await sbx.kill()
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python  
      # sandbox_compose.py
      from e2b import Sandbox

      sbx = Sandbox.create("docker-compose")

      sbx.commands.run("mkdir -p /tmp/docker-compose-test")
      sbx.files.write(
          "/tmp/docker-compose-test/compose.yaml",
          """
      services:
        hello:
          image: busybox:1.36
          command: ["sh", "-lc", "echo docker-compose-ok"]
      """,
      )

      result = 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
          """,
      )

      print(result.stdout)
      sbx.kill()
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

Expected output (example):

```text
hello_1  | docker-compose-ok
Docker Compose ran successfully
```
