v0.2 - Real Workspaces: - Project-specific claudebox StatefulSets (pantheon, aeries) - Init containers for git clone via SSH - Deploy key secrets template - Project ConfigMaps for CLAUDE.md v0.3 - Git Integration: - Dockerfile with rdev-bot git identity - openssh-client for SSH operations - Image version bump to v0.3.0 v0.4 - API Server: - Go REST API with chi router - Endpoints: /projects, /claude, /shell, /git, /events - SSE streaming for real-time output - OpenAPI docs via Scalar at /docs - Kubernetes RBAC for pod exec - Executor and project registry packages Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
5.6 KiB
5.6 KiB
rdev v0.2.0 - Real Workspaces
Date: 2026-01-24 Status: Ready for deployment (pending deploy keys)
Summary
Project-specific claudebox pods with real GitHub repository workspaces. Each project gets its own StatefulSet with an init container that clones the repo on first start.
What Was Built
Project-Specific StatefulSets
Two new claudebox deployments:
claudebox-pantheon- For the pantheon projectclaudebox-aeries- For the aeries project
Each has:
- Init container that clones repo via SSH
- Persistent workspace (20Gi)
- Persistent Claude config (1Gi)
- SSH deploy keys for GitHub access
- Project-specific CLAUDE.md via ConfigMap
Init Container Logic
# Setup SSH
mkdir -p /root/.ssh
cp /ssh-keys/id_ed25519 /root/.ssh/id_ed25519
chmod 600 /root/.ssh/id_ed25519
# Clone or fetch
if [ ! -d /workspace/.git ]; then
git clone git@github.com:orchard9/${PROJECT}.git /workspace
else
cd /workspace && git fetch origin
fi
Files Created
deployments/k8s/base/
├── claudebox-pantheon.yaml # Pantheon StatefulSet
├── claudebox-aeries.yaml # Aeries StatefulSet
├── pvc-pantheon.yaml # Pantheon PVCs
├── pvc-aeries.yaml # Aeries PVCs
├── configmaps.yaml # Project CLAUDE.md files
└── secrets.yaml # Deploy key secrets (template)
scripts/
└── generate-deploy-key.sh # Deploy key generation helper
Kubernetes Resources
| Resource | Type | Project |
|---|---|---|
| claudebox-pantheon | StatefulSet | pantheon |
| claudebox-aeries | StatefulSet | aeries |
| claudebox-pantheon-workspace | PVC (20Gi) | pantheon |
| claudebox-pantheon-claude-config | PVC (1Gi) | pantheon |
| claudebox-aeries-workspace | PVC (20Gi) | aeries |
| claudebox-aeries-claude-config | PVC (1Gi) | aeries |
| claudebox-pantheon-config | ConfigMap | pantheon |
| claudebox-aeries-config | ConfigMap | aeries |
| github-deploy-key-pantheon | Secret | pantheon |
| github-deploy-key-aeries | Secret | aeries |
Deployment Instructions
1. Generate Deploy Keys
cd /path/to/rdev
# Generate key for pantheon
./scripts/generate-deploy-key.sh pantheon
# Generate key for aeries
./scripts/generate-deploy-key.sh aeries
2. Add Public Keys to GitHub
For each project:
- Go to
https://github.com/orchard9/<project>/settings/keys - Click "Add deploy key"
- Title:
rdev-<project> - Paste contents of
<project>-deploy-key.pub - Check "Allow write access" (needed for v0.3)
3. Update Secrets
Edit deployments/k8s/base/secrets.yaml:
- Replace
REPLACE_WITH_BASE64_ENCODED_PRIVATE_KEYwith contents of<project>-deploy-key.b64
4. Deploy
export KUBECONFIG=~/.kube/orchard9-k3sf.yaml
kubectl apply -k deployments/k8s/base
5. Verify
# Check pods
kubectl get pods -n rdev
# Should show: claudebox-pantheon-0, claudebox-aeries-0
# Check init container logs
kubectl logs -n rdev claudebox-pantheon-0 -c git-clone
# Verify repo was cloned
kubectl exec -n rdev claudebox-pantheon-0 -- ls /workspace
kubectl exec -n rdev claudebox-pantheon-0 -- git -C /workspace status
# Authenticate Claude (first time only)
kubectl exec -it -n rdev claudebox-pantheon-0 -- claude
Key Decisions
1. Reuse claudebox image for init container
- Same image has git installed
- No need for separate alpine/git image
- Simpler to maintain
2. SSH Deploy Keys vs HTTPS PAT
- SSH deploy keys are per-repo (more secure)
- Aligns with v0.3 requirements (push access)
- GitHub deploy keys can have write access
3. ConfigMap for CLAUDE.md
- Allows customizing Claude behavior per project
- Mounted at /workspace/CLAUDE.md
- Can be updated without rebuilding image
4. Keep generic claudebox from v0.1
- Useful for testing/development
- No project-specific config required
- Can be used as template
Architecture
rdev namespace
├── claudebox-0 (v0.1 - generic)
│ └── /workspace (empty, for testing)
│
├── claudebox-pantheon-0 (v0.2)
│ ├── /workspace (pantheon repo)
│ ├── /root/.claude (Claude auth)
│ └── /root/.ssh (deploy key)
│
└── claudebox-aeries-0 (v0.2)
├── /workspace (aeries repo)
├── /root/.claude (Claude auth)
└── /root/.ssh (deploy key)
What's Next (v0.3)
- Git config (user.name, user.email) for commits
- Test git push from inside pod
- Proper SSH key mounting for main container (currently init-only)
Commands Reference
# Set kubeconfig
export KUBECONFIG=~/.kube/orchard9-k3sf.yaml
# Deploy
kubectl apply -k deployments/k8s/base
# Check status
kubectl get pods -n rdev
kubectl get pvc -n rdev
# View init container logs
kubectl logs -n rdev claudebox-pantheon-0 -c git-clone
# Interactive Claude session
kubectl exec -it -n rdev claudebox-pantheon-0 -- claude
# Run Claude with prompt
kubectl exec -it -n rdev claudebox-pantheon-0 -- claude "what files are in this project?"
# Git status
kubectl exec -n rdev claudebox-pantheon-0 -- git -C /workspace status
# Shell access
kubectl exec -it -n rdev claudebox-pantheon-0 -- bash
Troubleshooting
Init container fails with "Permission denied (publickey)"
- Verify deploy key is added to GitHub
- Check secret has correct base64-encoded private key
- Ensure known_hosts includes github.com
Workspace is empty after pod starts
- Check init container logs:
kubectl logs -n rdev <pod> -c git-clone - Verify SSH key permissions (should be 600)
Claude auth not persisting
- Check PVC is bound:
kubectl get pvc -n rdev - Verify claude-config volume is mounted at /root/.claude