# rdev v0.1.0 - Base Case

**Date**: 2026-01-24
**Status**: Deployed and verified

## Summary

First deployment of rdev - a single claudebox pod running on k3s with Claude Code CLI.

## What Was Built

### Container Image
- **Image**: `ghcr.io/orchard9/rdev-claudebox:v0.1.0`
- **Base**: Ubuntu 22.04
- **Platform**: linux/amd64 (k3s nodes are amd64, built from arm64 Mac)
- **Contents**:
  - Node.js 20 (required for Claude Code CLI)
  - Claude Code CLI v2.1.19
  - Git, vim, build-essential
  - Healthcheck script

### Kubernetes Resources
- **Namespace**: `rdev`
- **StatefulSet**: `claudebox` (1 replica)
- **PVCs**:
  - `claudebox-workspace` (20Gi) - for project files
  - `claudebox-claude-config` (1Gi) - for Claude auth persistence
- **Service**: `claudebox` (headless)
- **Secret**: `ghcr-secret` (copied from apps namespace)

### Resource Limits
```yaml
requests:
  cpu: "500m"
  memory: "1Gi"
limits:
  cpu: "2"
  memory: "4Gi"
```

## Key Decisions

### 1. GitHub Container Registry over GCP Artifact Registry
- This is an on-prem k3s cluster, not GKE
- Already have ghcr-secret for other images
- No gcloud dependency

### 2. PVC for Claude Config instead of Secret
- Claude credentials are too large for K8s secrets (>3MB limit)
- Auth persists across pod restarts
- User authenticates once via `kubectl exec`

### 3. Platform-specific Build
- k3s nodes are amd64
- Mac builds arm64 by default
- Added `--platform linux/amd64` to docker build

## Authentication

Claude Code authenticates via OAuth. To authenticate:

```bash
export KUBECONFIG=~/.kube/orchard9-k3sf.yaml
kubectl exec -it -n rdev claudebox-0 -- claude
```

This opens interactive mode. First run triggers OAuth flow - follow the URL to authenticate. Auth persists in the PVC.

## Verification

```bash
# Check pod status
kubectl get pods -n rdev
# NAME          READY   STATUS    RESTARTS   AGE
# claudebox-0   1/1     Running   0          58s

# Check Claude version
kubectl exec -n rdev claudebox-0 -- claude --version
# 2.1.19 (Claude Code)

# Test Claude (after auth)
kubectl exec -it -n rdev claudebox-0 -- claude "say hello"
```

## Files Created

```
rdev/
├── CLAUDE.md                           # Project instructions
├── README.md                           # Setup guide
├── Dockerfile                          # claudebox image
├── .gitignore
├── docs/
│   └── reference.md                    # Original reference guide
├── deployments/
│   └── k8s/
│       └── base/
│           ├── kustomization.yaml
│           ├── namespace.yaml
│           ├── pvc.yaml                # workspace + claude-config PVCs
│           └── claudebox.yaml          # StatefulSet + Service
├── scripts/
│   ├── build-push.sh                   # Build and push to ghcr.io
│   ├── deploy.sh                       # Deploy to k3s
│   ├── verify.sh                       # Verify deployment
│   └── create-credentials-secret.sh    # (deprecated - using PVC now)
└── history/
    └── v0.1.0.md                       # This file
```

## Issues Encountered

### 1. Image Pull Failed - Wrong Platform
- **Error**: `no match for platform in manifest: not found`
- **Cause**: Built arm64 image on Mac, k3s nodes are amd64
- **Fix**: Added `--platform linux/amd64` to docker build

### 2. Credentials Secret Too Large
- **Error**: `Request entity too large: limit is 3145728`
- **Cause**: ~/.claude directory is ~30MB (history, debug logs, etc.)
- **Fix**: Switched to PVC for claude config instead of mounting from secret

### 3. GCP Artifact Registry Auth Failed
- **Error**: `403 Forbidden` when pushing to us-central1-docker.pkg.dev
- **Cause**: Wrong approach - this is k3s, not GKE
- **Fix**: Switched to GitHub Container Registry (ghcr.io)

## What's Next (v0.2)

1. Mount real project workspaces (pantheon, aeries repos)
2. Add SSH keys for git push/pull
3. Multiple claudebox pods (one per project)
4. Project-specific environment configurations

## Commands Reference

```bash
# Set kubeconfig (REQUIRED)
export KUBECONFIG=~/.kube/orchard9-k3sf.yaml

# Deploy
kubectl apply -k deployments/k8s/base

# Check status
kubectl get pods -n rdev

# Interactive Claude session
kubectl exec -it -n rdev claudebox-0 -- claude

# Run Claude with prompt
kubectl exec -it -n rdev claudebox-0 -- claude "your prompt here"

# Shell access
kubectl exec -it -n rdev claudebox-0 -- bash

# View logs
kubectl logs -n rdev claudebox-0

# Restart pod
kubectl delete pod -n rdev claudebox-0
```
