# Docker
<subtitle>安装了 Docker 或 Docker Compose 的沙箱，用于运行容器。</subtitle>

## Docker

### 模板

使用来自 [get.docker.com](https://get.docker.com) 的官方安装脚本。运行 `hello-world` 容器可验证安装。

```python
# template.py
from ucloud_sandbox 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")
)
```

### 构建

我们建议至少使用 2 个 CPU 和 2 GB 内存来运行 Docker 容器。**内存较低时，您的沙箱可能会耗尽内存。**

```python
# build.py
from ucloud_sandbox 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(),
)
```

### 运行

运行一个打印 hello 消息的 Alpine 容器。

```python
# sandbox.py
from ucloud_sandbox import Sandbox

sbx = Sandbox.create('docker')

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

sbx.kill()
```

## Docker Compose

此示例安装 Docker 和 Docker Compose，然后通过 Compose 版本检查和示例 Compose 运行来验证设置。

### 模板

创建一个名为 `template_compose.py` 的新文件。

```python
# template_compose.py
from ucloud_sandbox 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",
        ]
    )
)
```

预期结果：您现在拥有一个本地 `template_compose.py` 文件。

### 构建

```python
# build_compose.py
from ucloud_sandbox 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(),
)
```

预期输出（示例）：

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

### 运行

```python
# sandbox_compose.py
from ucloud_sandbox 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()
```

预期输出（示例）：

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