This commit captures the current state before implementing the composable monorepo template system. Key changes included: Infrastructure: - Add CockroachDB provisioner adapter for database provisioning - Add Redis provisioner adapter for cache provisioning - Add build events system with PostgreSQL storage - Add WebSocket endpoint for real-time build progress Code agent improvements: - Fix Claude Code adapter to use default allowed tools instead of dangerously-skip-permissions - Add context-aware stream closing for cancellation support - Improve parser tests for edge cases Build system: - Add build event constants and metrics - Remove deprecated git_operations.go (replaced by pod_git_operations.go) - Add rollback logic for multi-step provisioning operations Documentation: - Add composable-monorepo feature documentation - Add DNS/Cloudflare service documentation - Update deployment and troubleshooting guides Cookbooks: - Add fullstack-app cookbook - Refactor landing-test with shared library Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
384 lines
13 KiB
Markdown
384 lines
13 KiB
Markdown
# Full-Stack App Cookbook
|
|
|
|
> Deploy a full-stack application (Next.js + Go backend) built entirely by Claude through the threesix.ai infrastructure.
|
|
|
|
## Overview
|
|
|
|
This cookbook creates and deploys a complete full-stack application using **agent-driven development**:
|
|
|
|
```
|
|
POST /project/create-and-build
|
|
↓
|
|
Creates: Gitea repo + DNS + Woodpecker CI + K8s deployment
|
|
↓
|
|
Enqueues build task with comprehensive prompt
|
|
↓
|
|
Worker picks up task → Claude builds the entire stack
|
|
↓
|
|
Agent commits + pushes
|
|
↓
|
|
CI builds and deploys
|
|
↓
|
|
Live full-stack app
|
|
```
|
|
|
|
**Claude builds everything from scratch: Next.js frontend with shadcn/ui, Go backend API, Docker configs, and CI pipeline.**
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
### API Access
|
|
```bash
|
|
export RDEV_API_URL="https://rdev.masq-ops.orchard9.ai"
|
|
export RDEV_API_KEY="<your-api-key>"
|
|
```
|
|
|
|
### Infrastructure Required
|
|
- rdev-api running with embedded worker
|
|
- Gitea at https://git.threesix.ai
|
|
- Woodpecker CI at https://ci.threesix.ai
|
|
- claudebox-0 pod running in rdev namespace
|
|
|
|
---
|
|
|
|
## Step 1: Create Project and Build Full-Stack App
|
|
|
|
Single API call that creates infrastructure AND enqueues the full-stack build:
|
|
|
|
```bash
|
|
curl -X POST "$RDEV_API_URL/project/create-and-build" \
|
|
-H "X-API-Key: $RDEV_API_KEY" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"name": "my-fullstack-app",
|
|
"description": "Full-stack app with Next.js frontend and Go backend",
|
|
"build": {
|
|
"prompt": "Build a full-stack task management application with the following structure:\n\nFRONTEND (Next.js 14 + shadcn/ui):\n- Create a Next.js 14 app with App Router in /frontend\n- Use shadcn/ui for all components (install with npx shadcn-ui@latest init)\n- Dark theme with modern aesthetic\n- Pages: Dashboard showing tasks, Add Task form, Task detail view\n- Use Tailwind CSS for styling\n- Connect to backend API at /api proxy\n\nBACKEND (Go):\n- Create a Go HTTP server in /backend using chi router\n- Endpoints: GET /api/tasks, POST /api/tasks, GET /api/tasks/{id}, DELETE /api/tasks/{id}\n- In-memory task storage (no database needed)\n- Structured JSON responses\n- CORS middleware for frontend\n\nDOCKER:\n- /frontend/Dockerfile: Multi-stage build for Next.js (node:20-alpine)\n- /backend/Dockerfile: Multi-stage build for Go (golang:1.22-alpine)\n- /docker-compose.yml: Run both services, frontend proxies to backend\n\nCI/CD:\n- /.woodpecker.yml: Build both images, push to registry, deploy to k8s\n\nCreate all necessary files including package.json, go.mod, and configuration files.",
|
|
"auto_commit": true,
|
|
"auto_push": true
|
|
}
|
|
}'
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"project": {
|
|
"project_id": "my-fullstack-app",
|
|
"domain": "xyz789ab.threesix.ai",
|
|
"git": {
|
|
"html_url": "https://git.threesix.ai/jordan/my-fullstack-app"
|
|
}
|
|
},
|
|
"build": {
|
|
"task_id": "task-uuid",
|
|
"status": "pending",
|
|
"status_url": "/builds/task-uuid"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Step 2: Monitor Build Progress
|
|
|
|
Poll the build status:
|
|
|
|
```bash
|
|
curl -s "$RDEV_API_URL/builds/{task_id}" \
|
|
-H "X-API-Key: $RDEV_API_KEY" | jq .
|
|
```
|
|
|
|
**Status progression:** `pending` → `running` → `completed` (or `failed`)
|
|
|
|
Full-stack builds take longer than simple landing pages. Expect 2-5 minutes.
|
|
|
|
When completed:
|
|
```json
|
|
{
|
|
"task_id": "task-uuid",
|
|
"status": "completed",
|
|
"result": {
|
|
"success": true,
|
|
"commit_sha": "def456",
|
|
"files_changed": [
|
|
"frontend/package.json",
|
|
"frontend/app/page.tsx",
|
|
"frontend/app/layout.tsx",
|
|
"frontend/components/task-list.tsx",
|
|
"frontend/components/add-task-form.tsx",
|
|
"frontend/Dockerfile",
|
|
"backend/main.go",
|
|
"backend/go.mod",
|
|
"backend/Dockerfile",
|
|
"docker-compose.yml",
|
|
".woodpecker.yml"
|
|
],
|
|
"duration_ms": 180000
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Step 3: Monitor CI Pipeline
|
|
|
|
The agent's push triggers Woodpecker CI to build both services:
|
|
|
|
```bash
|
|
curl -s "$RDEV_API_URL/projects/my-fullstack-app/pipelines" \
|
|
-H "X-API-Key: $RDEV_API_KEY" | jq '.data[0]'
|
|
```
|
|
|
|
Pipeline stages:
|
|
1. Build frontend Docker image
|
|
2. Build backend Docker image
|
|
3. Push both to registry
|
|
4. Deploy to Kubernetes
|
|
|
|
Wait for `status: "success"`.
|
|
|
|
---
|
|
|
|
## Step 4: Verify Deployment
|
|
|
|
```bash
|
|
# Check site is live
|
|
curl -I https://xyz789ab.threesix.ai
|
|
|
|
# Test frontend loads
|
|
curl -s https://xyz789ab.threesix.ai | head -20
|
|
|
|
# Test backend API
|
|
curl -s https://xyz789ab.threesix.ai/api/tasks | jq .
|
|
|
|
# Open in browser
|
|
open https://xyz789ab.threesix.ai
|
|
```
|
|
|
|
---
|
|
|
|
## Iterating on the App
|
|
|
|
### Add a Feature
|
|
|
|
```bash
|
|
curl -X POST "$RDEV_API_URL/projects/my-fullstack-app/builds" \
|
|
-H "X-API-Key: $RDEV_API_KEY" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"prompt": "Add task priority levels (low, medium, high) with color-coded badges in the UI. Update the backend Task struct and frontend components to support priorities. Add a priority filter dropdown on the dashboard.",
|
|
"auto_commit": true,
|
|
"auto_push": true
|
|
}'
|
|
```
|
|
|
|
### Fix a Bug
|
|
|
|
```bash
|
|
curl -X POST "$RDEV_API_URL/projects/my-fullstack-app/builds" \
|
|
-H "X-API-Key: $RDEV_API_KEY" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"prompt": "Fix the task deletion - ensure the DELETE endpoint returns 204 No Content and the frontend removes the task from the list immediately without requiring a page refresh.",
|
|
"auto_commit": true,
|
|
"auto_push": true
|
|
}'
|
|
```
|
|
|
|
### Add Authentication
|
|
|
|
```bash
|
|
curl -X POST "$RDEV_API_URL/projects/my-fullstack-app/builds" \
|
|
-H "X-API-Key: $RDEV_API_KEY" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"prompt": "Add simple JWT authentication:\n- Backend: Add /api/auth/login endpoint that accepts username/password and returns JWT\n- Backend: Add auth middleware to protect /api/tasks endpoints\n- Frontend: Add login page with shadcn form components\n- Frontend: Store JWT in localStorage, include in API requests\n- Create a demo user (admin/admin123) for testing",
|
|
"auto_commit": true,
|
|
"auto_push": true
|
|
}'
|
|
```
|
|
|
|
Each build:
|
|
1. Claude clones the existing repo
|
|
2. Makes the requested changes
|
|
3. Commits and pushes
|
|
4. CI deploys automatically
|
|
|
|
---
|
|
|
|
## Alternative Prompts
|
|
|
|
### E-commerce Storefront
|
|
|
|
```bash
|
|
curl -X POST "$RDEV_API_URL/project/create-and-build" \
|
|
-H "X-API-Key: $RDEV_API_KEY" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"name": "my-store",
|
|
"description": "E-commerce storefront",
|
|
"build": {
|
|
"prompt": "Build an e-commerce storefront:\n\nFRONTEND: Next.js 14 with shadcn/ui, dark theme\n- Product grid with images, prices, descriptions\n- Product detail page\n- Shopping cart (localStorage)\n- Checkout form (no payment processing)\n\nBACKEND: Go with chi router\n- GET /api/products - list products\n- GET /api/products/{id} - product detail\n- POST /api/orders - create order (log to console)\n- Seed with 6 sample products\n\nInclude Dockerfiles and .woodpecker.yml for CI/CD.",
|
|
"auto_commit": true,
|
|
"auto_push": true
|
|
}
|
|
}'
|
|
```
|
|
|
|
### Dashboard App
|
|
|
|
```bash
|
|
curl -X POST "$RDEV_API_URL/project/create-and-build" \
|
|
-H "X-API-Key: $RDEV_API_KEY" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"name": "my-dashboard",
|
|
"description": "Analytics dashboard",
|
|
"build": {
|
|
"prompt": "Build an analytics dashboard:\n\nFRONTEND: Next.js 14 with shadcn/ui + recharts\n- Dashboard with 4 stat cards (users, revenue, orders, growth)\n- Line chart showing weekly trends\n- Bar chart showing top products\n- Recent activity table\n- Dark theme, responsive grid layout\n\nBACKEND: Go with chi router\n- GET /api/stats - return dashboard statistics\n- GET /api/trends - return weekly trend data\n- GET /api/activity - return recent activity\n- Generate realistic sample data\n\nInclude Dockerfiles and .woodpecker.yml for CI/CD.",
|
|
"auto_commit": true,
|
|
"auto_push": true
|
|
}
|
|
}'
|
|
```
|
|
|
|
---
|
|
|
|
## Adding Custom Domains
|
|
|
|
```bash
|
|
# Add custom domain
|
|
curl -X POST "$RDEV_API_URL/projects/my-fullstack-app/domains" \
|
|
-H "X-API-Key: $RDEV_API_KEY" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"domain": "app.mycompany.com"}'
|
|
|
|
# List all domains
|
|
curl -s "$RDEV_API_URL/projects/my-fullstack-app/domains" \
|
|
-H "X-API-Key: $RDEV_API_KEY" | jq '.data.domains'
|
|
```
|
|
|
|
---
|
|
|
|
## Teardown
|
|
|
|
```bash
|
|
curl -X DELETE "$RDEV_API_URL/project/my-fullstack-app" \
|
|
-H "X-API-Key: $RDEV_API_KEY"
|
|
```
|
|
|
|
Removes: DNS records, K8s deployment, project metadata. Gitea repo preserved for safety.
|
|
|
|
---
|
|
|
|
## E2E Test Script
|
|
|
|
Run the full flow:
|
|
```bash
|
|
./cookbooks/scripts/fullstack-test.sh run my-test-fullstack
|
|
```
|
|
|
|
Check status:
|
|
```bash
|
|
./cookbooks/scripts/fullstack-test.sh status my-test-fullstack
|
|
```
|
|
|
|
Cleanup:
|
|
```bash
|
|
./cookbooks/scripts/fullstack-test.sh teardown my-test-fullstack
|
|
```
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────┐
|
|
│ Agent-Driven Full-Stack App │
|
|
│ │
|
|
│ POST /project/create-and-build │
|
|
│ │ │
|
|
│ ├──► Gitea: creates repo │
|
|
│ ├──► Cloudflare: creates DNS │
|
|
│ ├──► Woodpecker: activates CI │
|
|
│ ├──► K8s: creates Deployment/Service/Ingress │
|
|
│ └──► Work Queue: enqueues build task │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ Worker polls queue, claims task │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ Claude Code executes in claudebox-0: │
|
|
│ - Clones repo │
|
|
│ - Creates Next.js frontend with shadcn/ui │
|
|
│ - Creates Go backend with chi router │
|
|
│ - Writes Dockerfiles and CI config │
|
|
│ - Commits and pushes │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ Woodpecker CI triggered by push: │
|
|
│ - Builds frontend Docker image │
|
|
│ - Builds backend Docker image │
|
|
│ - Pushes to registry │
|
|
│ - Deploys to K8s │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ Full-stack app live at https://{slug}.threesix.ai │
|
|
│ - Frontend: Next.js + shadcn/ui │
|
|
│ - Backend: Go API │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Build stuck in pending
|
|
```bash
|
|
# Check worker status
|
|
curl -s "$RDEV_API_URL/workers" -H "X-API-Key: $RDEV_API_KEY" | jq '.data.summary'
|
|
|
|
# Should show at least 1 idle worker
|
|
```
|
|
|
|
### Build failed
|
|
```bash
|
|
# Get build details with full output
|
|
curl -s "$RDEV_API_URL/builds/{task_id}" -H "X-API-Key: $RDEV_API_KEY" | jq '.result'
|
|
|
|
# Check rdev-api logs for worker errors
|
|
./scripts/logs.sh -e
|
|
```
|
|
|
|
### Pipeline not triggering
|
|
```bash
|
|
# Check if commit was pushed
|
|
curl -s "https://git.threesix.ai/api/v1/repos/jordan/my-fullstack-app/commits" | jq '.[0]'
|
|
|
|
# Check Woodpecker
|
|
open https://ci.threesix.ai/jordan/my-fullstack-app
|
|
```
|
|
|
|
### Frontend/Backend connection issues
|
|
```bash
|
|
# Check both containers are running
|
|
kubectl get pods -n projects -l app=my-fullstack-app
|
|
|
|
# Check frontend logs
|
|
kubectl logs -n projects -l app=my-fullstack-app -c frontend
|
|
|
|
# Check backend logs
|
|
kubectl logs -n projects -l app=my-fullstack-app -c backend
|
|
```
|
|
|
|
---
|
|
|
|
## Related
|
|
|
|
- [Landing Page Cookbook](./landing-page.md) - Simpler single-page deployment
|
|
- [Worker Pool Guide](../.claude/guides/services/worker-pool.md)
|
|
- [Build Orchestration](../.claude/guides/services/build-orchestration.md)
|