diff --git a/docs/superpowers/specs/2026-04-03-deploy-demo-design.md b/docs/superpowers/specs/2026-04-03-deploy-demo-design.md new file mode 100644 index 00000000..19049ef6 --- /dev/null +++ b/docs/superpowers/specs/2026-04-03-deploy-demo-design.md @@ -0,0 +1,153 @@ +# Cameleer Deploy Demo + +## Goal + +Standalone demo prototype: upload a Camel JAR, build a container image with the cameleer3 monitoring agent injected, deploy to k3s, and see full observability appear in cameleer3-server. + +## Project + +New repo: `cameleer/cameleer-deploy-demo` on Gitea. Spring Boot 3 backend + React UI using `@cameleer/design-system`. + +## Architecture + +``` +Browser (React + DS) + ├─ Dashboard: table of deployed apps (status, resources, links) + └─ Deploy dialog: upload JAR, configure resources/env, stream build log + │ + ▼ +Deploy Service (Spring Boot 3, Java 21, port 8082) + ├─ POST /api/apps — upload JAR + config, start build pipeline + ├─ GET /api/apps — list deployed apps with K8s status + ├─ GET /api/apps/{name}/status — single app status + pod details + ├─ GET /api/apps/{name}/logs — build log (stored in memory) + ├─ DELETE /api/apps/{name} — undeploy (kubectl delete + registry cleanup) + │ + Build Pipeline (per deploy): + │ 1. Save JAR to temp dir + │ 2. Generate Dockerfile (JRE + agent from Maven + customer JAR) + │ 3. docker build → tag as gitea.siegeln.net/cameleer/demo-apps/: + │ 4. docker push to Gitea container registry + │ 5. kubectl apply Deployment to cameleer-demo namespace + │ 6. Cleanup temp dir + │ + └─ In-memory state (ConcurrentHashMap) + │ + ├─► Gitea Container Registry (images) + ├─► k3s cluster / cameleer-demo namespace (workloads) + └─► cameleer3-server (agents auto-register via bootstrap token) +``` + +## No Auth + +Demo only. No authentication, no RBAC. Big "DEMO" banner in UI. + +## Build Pipeline Detail + +Generated Dockerfile per app: + +```dockerfile +FROM eclipse-temurin:21-jre-alpine + +ADD https://gitea.siegeln.net/api/packages/cameleer/maven/com/cameleer3/cameleer3-agent/1.0-SNAPSHOT/cameleer3-agent-1.0-SNAPSHOT.jar /opt/cameleer/agent.jar + +COPY app.jar /opt/app/app.jar + +ENV CAMELEER_SERVER_URL=http://cameleer3-server.cameleer.svc:8081 +ENV CAMELEER_APP_NAME= +ENV CAMELEER_AUTH_TOKEN= + +ENTRYPOINT ["java", "-javaagent:/opt/cameleer/agent.jar", "-jar", "/opt/app/app.jar"] +``` + +Agent snapshot JAR downloaded at build time from Gitea Maven registry. Bootstrap token configured via deploy service env var. + +## K8s Deployment + +Each app gets a Deployment in the `cameleer-demo` namespace: + +- Resource requests/limits from user config (defaults: 250m/256Mi requests, 500m/512Mi limits) +- User-provided env vars injected into the container spec +- No Service or Ingress (apps only need outbound access to cameleer3-server) +- Labels: `app.kubernetes.io/managed-by: cameleer-deploy`, `cameleer/app-name: ` + +## Data Model (In-Memory) + +```java +record DeployedApp( + String name, + String imageName, + String imageTag, + DeployStatus status, // BUILDING, PUSHING, DEPLOYING, RUNNING, FAILED, DELETED + String statusMessage, + ResourceConfig resources, + Map envVars, + Instant createdAt +) + +record ResourceConfig( + String cpuRequest, // default "250m" + String memoryRequest, // default "256Mi" + String cpuLimit, // default "500m" + String memoryLimit // default "512Mi" +) +``` + +On GET /api/apps, reconcile status with actual K8s pod phase via kubectl. On startup, scan `cameleer-demo` namespace to rediscover deployed apps. + +## UI + +**Dashboard page:** + +| Column | Content | +|--------|---------| +| Name | Clickable → cameleer3-server exchanges page | +| Status | Badge: Running / Pending / Failed / Building | +| Image | Image tag (mono text) | +| Resources | CPU/Memory limits | +| Age | Time since deploy | +| Actions | Delete button with confirm dialog | + +"Deploy Application" button opens a dialog: +- App Name (text, validated: lowercase, alphanumeric, hyphens) +- JAR File (drag-and-drop, accepts .jar) +- Resource Limits: CPU + Memory (two pairs: requests and limits) +- Environment Variables: key/value table with add/remove +- Deploy button → switches to streaming build log view +- On success: closes dialog, app appears in table +- On failure: log stays visible with error + +Status polling: GET /api/apps every 5 seconds. + +All components from @cameleer/design-system. CSS modules for layout. + +## Configuration + +Deploy service env vars: +- `CAMELEER_SERVER_URL` — cameleer3-server URL for agent registration (default: `http://cameleer3-server.cameleer.svc:8081`) +- `CAMELEER_BOOTSTRAP_TOKEN` — bootstrap token for agent registration +- `CAMELEER_REGISTRY` — container registry prefix (default: `gitea.siegeln.net/cameleer/demo-apps`) +- `CAMELEER_AGENT_MAVEN_URL` — URL for agent snapshot JAR +- `CAMELEER_DEMO_NAMESPACE` — K8s namespace for deployed apps (default: `cameleer-demo`) +- `KUBECONFIG` — path to kubeconfig (or in-cluster config) + +## Tech Stack + +- Backend: Spring Boot 3.4, Java 21, spring-web +- Frontend: React 19, Vite, @cameleer/design-system, TypeScript +- Build: Maven (backend), npm (frontend) +- Container: Docker (multi-stage build) +- Deploy: k3s at 192.168.50.86, namespace `cameleer-demo` +- Registry: Gitea container registry +- Agent: cameleer3-agent 1.0-SNAPSHOT from Gitea Maven registry + +## Out of Scope + +- Authentication / RBAC +- Multi-tenancy +- Persistent storage (in-memory only) +- Ingress for deployed apps +- Horizontal scaling +- CI/CD pipeline for the demo app itself +- Health probes on deployed apps +- Log streaming from running apps (only build logs)