# Landing Page Cookbook > Deploy a static landing page through the threesix.ai infrastructure with agent-driven development. ## Overview This cookbook creates and deploys a simple landing page using the full threesix.ai autonomous infrastructure: ``` POST /project → Gitea repo + DNS + Woodpecker CI + template seed → Claude agent → git push → CI build → K8s deployment ``` **Target:** `landing.threesix.ai` (with future DNS aliases for www/root) **Stack:** Astro (static site generator) via `astro-landing` template **Status:** Coming Soon page --- ## What's Automated Today `POST /project` orchestrates the full infrastructure setup in a single call: | Step | Status | How | |------|--------|-----| | Gitea repo creation | Automated | `port.GitRepository` adapter | | DNS A record | Automated | `port.DNSProvider` (Cloudflare) adapter | | Woodpecker CI activation | Automated | `port.CIProvider` adapter, called during project creation | | Template seeding | Automated | `port.TemplateProvider` with `astro-landing` template | | K8s deployment | Automated | `port.Deployer` adapter (triggered by CI webhook) | ## Full Pipeline Status All infrastructure gaps have been closed. The full pipeline from project creation through code generation, CI monitoring, and multi-domain DNS is operational: | Capability | Endpoint | Status | |------------|----------|--------| | Project creation | `POST /project` | Operational | | Code generation (worker) | `POST /projects/{id}/builds` | Operational | | Create + build combo | `POST /project/create-and-build` | Operational | | CI pipeline monitoring | `GET /projects/{id}/pipelines` | Operational | | DNS alias management | `POST /projects/{id}/domains` | Operational | --- ## Prerequisites ### Credentials Required | Secret | Location | Purpose | |--------|----------|---------| | RDEV_ADMIN_KEY | `rdev-credentials` secret | rdev-api authentication | | GITEA_TOKEN | `rdev-credentials` secret | Gitea API access | | WOODPECKER_API_TOKEN | `rdev-credentials` secret | Woodpecker repo activation | | CLOUDFLARE_API_TOKEN | `rdev-credentials` secret | DNS management | ### Infrastructure Required - [x] rdev-api running with infrastructure handlers - [x] Gitea at https://git.threesix.ai - [x] Woodpecker CI at https://ci.threesix.ai - [x] Zot registry at zot.threesix.svc.cluster.local:5000 - [x] `projects` namespace in K8s with RBAC - [x] Wildcard TLS cert for *.threesix.ai --- ## Architecture ``` ┌──────────────────────────────────────────────────────────────────────┐ │ Landing Page Flow │ │ │ │ 1. Create Project (single API call) │ │ POST /project {"name": "landing", "template": "astro-landing"} │ │ │ │ │ ├──▶ Creates Gitea repo: threesix/landing │ │ ├──▶ Creates DNS: landing.threesix.ai → cluster IP │ │ ├──▶ Activates Woodpecker CI (auto) │ │ └──▶ Seeds repo with astro-landing template │ │ │ │ 2. Generate Code (3 options) │ │ Via worker pool, claudebox, or local Claude Code │ │ │ │ │ ├──▶ Customizes Astro landing page │ │ ├──▶ Commits and pushes to Gitea │ │ └──▶ Worker executor polls queue, dispatches to agent │ │ │ │ 3. CI/CD Pipeline (automatic on push) │ │ Woodpecker triggered by git push │ │ │ │ │ ├──▶ npm install + npm build │ │ ├──▶ Docker build (nginx) │ │ ├──▶ Push to Zot registry │ │ └──▶ kubectl set image (deploy) │ │ │ │ 4. Live at https://landing.threesix.ai │ │ │ └──────────────────────────────────────────────────────────────────────┘ ``` --- ## Step-by-Step Implementation ### Step 1: Create Project via rdev-api This single call creates the Gitea repo, DNS record, activates Woodpecker CI, and seeds the repo with the `astro-landing` template. ```bash curl -X POST https://rdev.masq-ops.orchard9.ai/project \ -H "Authorization: Bearer $RDEV_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "landing", "description": "threesix.ai landing page", "template": "astro-landing" }' ``` **Response:** ```json { "project_id": "landing", "name": "landing", "description": "threesix.ai landing page", "git": { "owner": "threesix", "name": "landing", "clone_ssh": "git@git.threesix.ai:threesix/landing.git", "clone_http": "https://git.threesix.ai/threesix/landing.git", "html_url": "https://git.threesix.ai/threesix/landing" }, "domain": "landing.threesix.ai", "url": "https://landing.threesix.ai", "next_steps": [] } ``` If any infrastructure step fails, `next_steps` will contain manual instructions for that step. The remaining steps still execute. ### Step 2: Generate Code The `astro-landing` template seeds the repo with a working Astro project, Dockerfile, nginx.conf, and `.woodpecker.yml`. You can customize it via Claude. **Option A: Local Claude Code (recommended for now)** ```bash git clone https://git.threesix.ai/threesix/landing.git cd landing # Use Claude Code to customize the landing page # Then commit and push ``` **Option B: Via existing claudebox** ```bash curl -X POST "https://rdev.masq-ops.orchard9.ai/projects/pantheon/claude" \ -H "Authorization: Bearer $RDEV_KEY" \ -H "Content-Type: application/json" \ -d '{ "prompt": "Clone https://git.threesix.ai/threesix/landing.git to /tmp/landing, then customize the Astro landing page with: Coming Soon message, threesix.ai branding (dark theme, gradient background), responsive layout. Commit and push when done." }' ``` **Option C: Via work queue (build endpoint)** ```bash # Enqueue a build task for a worker to execute curl -X POST "https://rdev.masq-ops.orchard9.ai/projects/landing/builds" \ -H "Authorization: Bearer $RDEV_KEY" \ -H "Content-Type: application/json" \ -d '{ "prompt": "Customize the landing page with Coming Soon message and threesix.ai branding", "auto_commit": true, "auto_push": true }' ``` **Option D: Create + build in one call** ```bash curl -X POST "https://rdev.masq-ops.orchard9.ai/project/create-and-build" \ -H "Authorization: Bearer $RDEV_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "landing", "description": "threesix.ai landing page", "template": "astro-landing", "build": { "prompt": "Customize with Coming Soon message and threesix.ai branding", "auto_commit": true, "auto_push": true } }' ``` ### Step 3: Monitor Build The git push triggers Woodpecker CI automatically. **Via rdev-api (recommended):** ```bash # List recent pipelines curl -s "https://rdev.masq-ops.orchard9.ai/projects/landing/pipelines" \ -H "Authorization: Bearer $RDEV_KEY" | jq '.data.pipelines' # Get specific pipeline curl -s "https://rdev.masq-ops.orchard9.ai/projects/landing/pipelines/1" \ -H "Authorization: Bearer $RDEV_KEY" | jq '.data' ``` **Via Woodpecker UI:** - https://ci.threesix.ai/threesix/landing ### Step 4: Verify Deployment ```bash # Check project status via rdev-api curl -s "https://rdev.masq-ops.orchard9.ai/project/landing" \ -H "Authorization: Bearer $RDEV_KEY" | jq '.data.deployment' # Check deployment via K8s export KUBECONFIG=~/.kube/orchard9-k3sf.yaml kubectl get deploy -n projects landing # Check the site curl -I https://landing.threesix.ai ``` ### Step 5: Configure DNS Aliases (Optional) Point `www.threesix.ai` and `threesix.ai` to the landing page via the rdev-api domain alias endpoints. ```bash # Add www.threesix.ai as a CNAME alias curl -X POST "https://rdev.masq-ops.orchard9.ai/projects/landing/domains" \ -H "Authorization: Bearer $RDEV_KEY" \ -H "Content-Type: application/json" \ -d '{"domain": "www.threesix.ai", "type": "CNAME"}' # Add root A record curl -X POST "https://rdev.masq-ops.orchard9.ai/projects/landing/domains" \ -H "Authorization: Bearer $RDEV_KEY" \ -H "Content-Type: application/json" \ -d '{"domain": "threesix.ai"}' # List all domains for the project curl -s "https://rdev.masq-ops.orchard9.ai/projects/landing/domains" \ -H "Authorization: Bearer $RDEV_KEY" | jq '.data.domains' # Remove an alias curl -X DELETE "https://rdev.masq-ops.orchard9.ai/projects/landing/domains/www.threesix.ai" \ -H "Authorization: Bearer $RDEV_KEY" ``` --- ## Template: astro-landing The `astro-landing` template (`deployments/k8s/base/templates/astro-landing/`) seeds the repo with: | File | Purpose | |------|---------| | `.woodpecker.yml` | CI pipeline: npm build, Docker build, push, deploy | | `.claude/CLAUDE.md` | Project instructions for Claude Code | | `Dockerfile` | Multi-stage build (Node 20 build, nginx serve) | | `nginx.conf` | Production config with gzip, caching, SPA fallback | | `package.json` | Astro 4.0+ with Tailwind CSS | | `astro.config.mjs` | Astro configuration | | `tailwind.config.mjs` | Tailwind configuration | | `src/pages/index.astro` | Landing page (dark theme with gradient) | | `src/layouts/Layout.astro` | Base HTML layout | | `README.md` | Development and deployment docs | Variables substituted during seeding: `{{PROJECT_NAME}}`, `{{DOMAIN}}`, `{{GIT_URL}}` --- ## Implementation Status All components for the full landing page pipeline are implemented: | Component | Location | Status | |-----------|----------|--------| | Work queue (enqueue/dequeue) | `internal/adapter/postgres/work_queue.go` | Implemented | | Worker registry | `internal/adapter/postgres/worker_registry.go` | Implemented | | Build audit tracking | `internal/adapter/postgres/build_audit.go` | Implemented | | Build service | `internal/service/build_service.go` | Implemented | | Worker service | `internal/service/worker_service.go` | Implemented | | Work handlers (REST) | `internal/handlers/work.go` | Implemented | | Code agent interface | `internal/port/code_agent.go` | Implemented | | Worker executor daemon | `internal/worker/work_executor.go` | Implemented | | BuildSpec-to-agent bridge | `internal/worker/build_executor.go` | Implemented | | Git credential resolution | `internal/service/credential_service.go` | Implemented | | DNS alias endpoints | `internal/handlers/infrastructure_domains.go` | Implemented | | CI pipeline proxy | `internal/handlers/infrastructure_pipelines.go` | Implemented | | Create-and-build endpoint | `internal/handlers/create_and_build.go` | Implemented | --- ## Verification After deployment, verify: ```bash # Check DNS dig landing.threesix.ai # Check site curl -I https://landing.threesix.ai # Check deployment status curl https://rdev.masq-ops.orchard9.ai/project/landing \ -H "Authorization: Bearer $RDEV_KEY" ``` --- ## Rollback To remove the landing page: ```bash # Delete via rdev-api (removes DNS, K8s deployment; Gitea repo preserved for safety) curl -X DELETE https://rdev.masq-ops.orchard9.ai/project/landing \ -H "Authorization: Bearer $RDEV_KEY" ``` --- ## Related - [Build Orchestration](../ai-lookup/features/build-orchestration.md) - Build system documentation - [Worker Pool](../ai-lookup/services/worker-pool.md) - Worker pool management - [Work Queue](../.claude/guides/services/work-queue.md) - Work queue guide - [Templates](../.claude/guides/services/templates.md) - Project template guide