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>
213 lines
5.6 KiB
Markdown
213 lines
5.6 KiB
Markdown
# 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 project
|
|
- `claudebox-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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
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:
|
|
1. Go to `https://github.com/orchard9/<project>/settings/keys`
|
|
2. Click "Add deploy key"
|
|
3. Title: `rdev-<project>`
|
|
4. Paste contents of `<project>-deploy-key.pub`
|
|
5. Check "Allow write access" (needed for v0.3)
|
|
|
|
### 3. Update Secrets
|
|
|
|
Edit `deployments/k8s/base/secrets.yaml`:
|
|
- Replace `REPLACE_WITH_BASE64_ENCODED_PRIVATE_KEY` with contents of `<project>-deploy-key.b64`
|
|
|
|
### 4. Deploy
|
|
|
|
```bash
|
|
export KUBECONFIG=~/.kube/orchard9-k3sf.yaml
|
|
kubectl apply -k deployments/k8s/base
|
|
```
|
|
|
|
### 5. Verify
|
|
|
|
```bash
|
|
# 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)
|
|
|
|
1. Git config (user.name, user.email) for commits
|
|
2. Test git push from inside pod
|
|
3. Proper SSH key mounting for main container (currently init-only)
|
|
|
|
## Commands Reference
|
|
|
|
```bash
|
|
# 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
|