---
name: gvisor
description: >
  Use when the user wants to create, containerize, or test a sample application
  that runs under gVisor (runsc). Guides through app scaffolding, Dockerfile
  creation, OCI/Docker runtime configuration for gVisor, and validation of
  syscall compatibility — including reading the gVisor source and docs at
  https://github.com/google/gvisor.
---

# gVisor Application Builder

Follow these steps in order to build and validate a sample application
that runs securely under the gVisor container runtime (`runsc`).

---

## Step 1 — Clarify the Application

Use `ask_followup_question` to determine:

1. **Language / framework** — Go, Python, Node.js, Java, etc.?
2. **Purpose** — HTTP server, batch job, CLI tool, database client, etc.?
3. **Platform** — Docker + gVisor, Kubernetes with `RuntimeClass`, or bare `runsc`?
4. **Host OS** — Linux (required for gVisor); confirm if on macOS/Windows for VM-based setups.
5. **gVisor platform** — `ptrace` (universal, slower) or `KVM` (faster, needs hardware virt)?

If the user is on macOS or Windows, note that gVisor only runs on Linux, so a
Lima/Colima/Multipass VM or a Linux CI environment is required.

---

## Step 2 — Scaffold the Application

Create the application source under the `src/` directory following project conventions:

- Keep the application minimal and focused on demonstrating sandboxed execution.
- Use only **Linux syscalls that gVisor supports** (check the compatibility matrix at
  `https://gvisor.dev/docs/user_guide/compatibility/linux/amd64/` before using exotic syscalls).
- Avoid:
  - `io_uring` (partially supported, version-dependent)
  - `userfaultfd` (not supported)
  - Raw sockets (restricted by default)
  - `ptrace` inside the sandbox

Write a `README.md` section explaining what the app does and any gVisor-specific constraints.

---

## Step 3 — Write the Dockerfile

Create a `Dockerfile` that:

1. Uses a **minimal base image** (`gcr.io/distroless`, `alpine`, or `scratch` for Go binaries).
2. Runs as a **non-root user** (gVisor enforces UID mapping strictly).
3. Avoids volume mounts that use `fuse` or `overlay` filesystems unsupported by `runsc`.
4. Sets a clear `ENTRYPOINT`.

Example skeleton for a Go binary:
```dockerfile
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o app .

FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/app /app
ENTRYPOINT ["/app"]
```

---

## Step 4 — Configure Docker to Use gVisor (`runsc`)

Create a `scripts/setup-gvisor.sh` script that:

1. Installs `runsc` from the official release:
   `https://storage.googleapis.com/gvisor/releases/release/latest/x86_64/runsc`
2. Registers it as a Docker runtime:

```bash
sudo runsc install
sudo systemctl restart docker
```

3. Verifies the installation with:
```bash
docker run --runtime=runsc --rm hello-world
```

Also create a `docker-compose.yml` with:
```yaml
services:
  app:
    build: .
    runtime: runsc
    ports:
      - "8080:8080"
```

---

## Step 5 — Validate Syscall Compatibility

After building the image, run it under `runsc` in strace mode to surface any
unsupported syscall:

```bash
docker run --runtime=runsc --rm \
  -e "RUNSC_STRACE=1" \
  <image-name>
```

Check `dmesg` or Docker logs for `FATAL` or `unimplemented syscall` messages.

Consult `https://gvisor.dev/docs/user_guide/compatibility/` for the canonical
compatibility table. If a syscall is missing, either:
- Rewrite the code path to avoid it, or
- Switch to `--platform=kvm` which has broader support.

---

## Step 6 — Write Tests

Create `tests/` with at minimum:

1. **Unit tests** for the application logic.
2. **Integration test** that builds and runs the container with `--runtime=runsc`
   and asserts expected output/behavior (use `docker run` in a shell assertion or
   a language-native test harness).

Provide a `scripts/test.sh` that runs both levels.

---

## Step 7 — Document the Output

Update `README.md` with:

- Architecture diagram (Mermaid preferred) showing:
  `Host OS → gVisor (runsc) → Application sandbox`
- Prerequisites list (Linux host, Docker ≥ 20.10, gVisor installed).
- `docker-compose up` quick-start instructions.
- gVisor platform choice rationale (`ptrace` vs `KVM`).

Update `Architecture.md` with the Mermaid flow as per project conventions.

---

## Constraints & Reminders

- gVisor runs **Linux only** — always check host OS early (Step 1).
- Do not speculate about syscall support; always verify against `gvisor.dev/docs`.
- Scripts go in `scripts/`, output goes in `output/`, docs go in `Docs/`.
- Never use port 5000 on macOS (reserved by AirDrop).
- Always provide a `.gitignore` that excludes `.env`, `_*` folders, and `__pycache__`.
- Always provide a Python virtual environment when Python is the chosen language.
- When making updates, edit existing files — never create duplicates.
