# Cameleer Deploy Demo ## Goal Standalone demo prototype: upload a Camel JAR, build a container image with the cameleer monitoring agent injected, deploy to k3s, and see full observability appear in cameleer-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) └─► cameleer-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/cameleer/cameleer-agent/1.0-SNAPSHOT/cameleer-agent-1.0-SNAPSHOT.jar /opt/cameleer/agent.jar COPY app.jar /opt/app/app.jar ENV CAMELEER_SERVER_URL=http://cameleer-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 cameleer-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 → cameleer-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` — cameleer-server URL for agent registration (default: `http://cameleer-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: cameleer-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)