Files
cameleer-server/docs/superpowers/specs/2026-04-03-deploy-demo-design.md
hsiegeln a036d8a027 docs: spec for cameleer-deploy-demo prototype
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 00:13:04 +02:00

5.4 KiB

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/<name>:<ts>
  │  4. docker push to Gitea container registry
  │  5. kubectl apply Deployment to cameleer-demo namespace
  │  6. Cleanup temp dir
  │
  └─ In-memory state (ConcurrentHashMap<String, DeployedApp>)
        │
        ├─► 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:

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=<user-provided-name>
ENV CAMELEER_AUTH_TOKEN=<bootstrap-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: <name>

Data Model (In-Memory)

record DeployedApp(
    String name,
    String imageName,
    String imageTag,
    DeployStatus status,       // BUILDING, PUSHING, DEPLOYING, RUNNING, FAILED, DELETED
    String statusMessage,
    ResourceConfig resources,
    Map<String, String> 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)