fix: correct protocol version header, disable SQL logging, document deployment pipeline
All checks were successful
CI / build (push) Successful in 1m9s
CI / docker (push) Successful in 1m43s
SonarQube Analysis / sonarqube (push) Successful in 1m20s

- ServerApiClient: use X-Cameleer-Protocol-Version: 1 (server expects "1", not "2")
- Disable Hibernate show-sql in dev profile (too verbose)
- CLAUDE.md: document deployment pipeline architecture, M2M server role in bootstrap,
  runtime-base image in CI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-07 18:58:27 +02:00
parent 617785baa7
commit 30aaacb5b5
3 changed files with 22 additions and 4 deletions

View File

@@ -83,14 +83,31 @@ Separate Vite+React SPA replacing Logto's default sign-in page. Visually matches
The server's OIDC config (`OidcConfig`) includes `audience` (RFC 8707 resource indicator) and `additionalScopes`. The `audience` is sent as `resource` in both the authorization request and token exchange, which makes Logto return a JWT access token instead of opaque. The Custom JWT script maps org roles to `roles: ["server:admin"]`. If OIDC returns no roles and the user already exists, `syncOidcRoles` preserves existing local roles.
### Deployment pipeline
App deployment is fully async via `DeploymentExecutor` (separate `@Service` so Spring `@Async` proxy works):
1. Build image: `FROM cameleer-runtime-base:latest` + `COPY app.jar` (via `DockerRuntimeOrchestrator`)
2. Stop/remove old container (by deployment metadata + orphan name cleanup)
3. Start new container on the compose network with env vars (`CAMELEER_AUTH_TOKEN`, `CAMELEER_EXPORT_ENDPOINT`, etc.), Traefik labels, resource limits
4. Wait for Docker health check (`/cameleer/health` on agent port 9464)
5. Update deployment status to RUNNING or FAILED
Key files:
- `DeploymentExecutor.java` — async deployment logic, extracted from `DeploymentService` to avoid Spring `@Async` self-invocation
- `DockerRuntimeOrchestrator.java` — Docker client (zerodep transport for Unix socket), image build, container lifecycle
- `docker/runtime-base/Dockerfile` — base image with agent JAR, maps env vars to `-D` system properties
- `ServerApiClient.java` — M2M token acquisition for SaaS→server API calls (agent status). Uses `X-Cameleer-Protocol-Version: 1` header
- Docker socket access: `group_add: ["0"]` in docker-compose.yml (not root group membership in Dockerfile)
- Network: deployed containers join `${COMPOSE_PROJECT_NAME}_cameleer` network
### Bootstrap (`docker/logto-bootstrap.sh`)
Idempotent script run via `logto-bootstrap` init container. Phases:
1. Wait for Logto + server health
2. Get Management API token (reads `m-default` secret from DB)
3. Create Logto apps (SPA, Traditional with `skipConsent`, M2M with Management API role)
3. Create Logto apps (SPA, Traditional with `skipConsent`, M2M with Management API role + server API role)
3b. Create API resource scopes (10 platform + 3 server scopes)
4. Create org roles (owner, operator, viewer with API resource scope assignments)
4. Create org roles (owner, operator, viewer with API resource scope assignments) + M2M server role (`cameleer-m2m-server` with `server:admin` scope)
5. Create users (platform owner with Logto console access, viewer for testing read-only OIDC)
6. Create organization, add users with org roles (owner + viewer)
7. Configure cameleer3-server OIDC (`rolesClaim: "roles"`, `audience`, `defaultRoles: ["VIEWER"]`)
@@ -109,6 +126,7 @@ Platform owner credentials (`SAAS_ADMIN_USER`/`SAAS_ADMIN_PASS`) work for both t
- Docker images: CI builds and pushes all images — Dockerfiles use multi-stage builds, no local builds needed
- `cameleer-saas` — SaaS app (frontend + JAR baked in)
- `cameleer-logto` — custom Logto with sign-in UI baked in
- `cameleer-runtime-base` — base image for deployed apps (agent JAR + JRE). CI downloads latest agent SNAPSHOT from Gitea Maven registry
- Docker builds: `--no-cache`, `--provenance=false` for Gitea compatibility
- `docker-compose.dev.yml` — exposes ports for direct access, sets `SPRING_PROFILES_ACTIVE: dev`. Volume-mounts `./ui/dist` into the container so local UI builds are served without rebuilding the Docker image (`SPRING_WEB_RESOURCES_STATIC_LOCATIONS` overrides classpath)
- Design system: import from `@cameleer/design-system` (Gitea npm registry)