# Dev Container

> Set up the aibox Dev Container that carries every tool this project needs.

---

LLMS index: [llms.txt](/kubeclaw/llms.txt)

---

The project uses an aibox-generated Dev Container (Debian Trixie) as a
self-contained, reproducible environment. Nothing needs to be set up on the
host machine beyond Docker and an IDE with Dev Container support.

## What the Dev Container Provides

- **OpenTofu** -- infrastructure provisioning (Terraform-compatible)
- **Ansible** -- server management (runs inside the container, no host install needed)
- **cloudflared** -- SSH ProxyCommand via Cloudflare Tunnel
- **ssh-agent** -- start inside the container to use passphrase-protected keys with Ansible
- **AI CLI tools** -- Codex and the aibox toolchain
- **Hugo + Docsy** -- documentation site (`./scripts/serve-docs.sh` at port 1313)
- **Persistence** -- `.aibox-home/.ssh/` is bind-mounted read-write by this
  project, so `setup-ssh.sh` output, SSH config, and exported keys survive
  container rebuilds


## Step 1: Prepare Persistent Directories

Create the persistent directories before opening the Dev Container:

```bash
git clone <repo-url>
cd kubeclaw

# Create the persistent SSH directory mounted at /home/aibox/.ssh.
mkdir -p .aibox-home/.ssh
chmod 700 .aibox-home/.ssh
```

The `.aibox-home/` directory is gitignored. Its `.ssh/` subdirectory holds
your private keys, SSH configuration, and `known_hosts` without risking a
commit of secrets.

## Step 2: Open in Dev Container



<ul class="nav nav-tabs" id="tabs-0" role="tablist">
  <li class="nav-item">
      <button class="nav-link active"
          id="tabs-00-00-tab" data-bs-toggle="tab" data-bs-target="#tabs-00-00" role="tab"
          aria-controls="tabs-00-00" aria-selected="true">
        VS Code (recommended)
      </button>
    </li>
</ul>

<div class="tab-content" id="tabs-0-content">
    <div class="tab-pane fade show active"
        id="tabs-00-00" role="tabpanel" aria-labelled-by="tabs-00-00-tab" tabindex="0">
        <pre tabindex="0"><code>1. Install the [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension
2. Open the project folder in VS Code
3. Click **&#34;Reopen in Container&#34;** when prompted, or press ++cmd+shift+p++ and select **Dev Containers: Reopen in Container**</code></pre>
    </div>
</div>

The generated setup uses Docker Compose. Use your editor's Dev Container
command rather than `docker build` directly so the generated Compose mounts,
including the persistent aibox home directory, are applied.

## Step 3: Start SSH Agent

```bash
source ./scripts/ssh-agent-setup.sh
```

<div class="alert alert-primary" role="alert"><div class="h4 alert-heading" role="heading">Note</div>


No SSH keys exist yet at this point -- they are created later during [Infrastructure provisioning](/kubeclaw/docs/guide/infrastructure/). This step starts the ssh-agent and fixes SSH directory permissions, preparing the environment for later steps.

</div>

<div class="alert alert-primary" role="alert"><div class="h4 alert-heading" role="heading">Important</div>


The `source` command is required -- running the script without `source` starts the agent in a subprocess that terminates immediately.

</div>

<div class="alert alert-primary" role="alert"><div class="h4 alert-heading" role="heading">SSH persistence</div>


Docker bind mounts from macOS may not preserve Unix permissions. The
`ssh-agent-setup.sh` script automatically fixes SSH directory permissions on
every run.

The `.aibox-home/.ssh/` directory stores SSH private keys, SSH config, and
`known_hosts` -- all exported or generated by `setup-ssh.sh`. Everything
survives container rebuilds.
</div>


## Step 4: Verify Setup

Confirm that the essential tools are available:

```bash
tofu --version
ansible --version
hugo version
npm --version
```

Preview the documentation:

```bash
./scripts/serve-docs.sh
# Open http://localhost:1313 in your browser
```
