fix: correct protocol version header, disable SQL logging, document deployment pipeline
- 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:
22
CLAUDE.md
22
CLAUDE.md
@@ -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.
|
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`)
|
### Bootstrap (`docker/logto-bootstrap.sh`)
|
||||||
|
|
||||||
Idempotent script run via `logto-bootstrap` init container. Phases:
|
Idempotent script run via `logto-bootstrap` init container. Phases:
|
||||||
1. Wait for Logto + server health
|
1. Wait for Logto + server health
|
||||||
2. Get Management API token (reads `m-default` secret from DB)
|
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)
|
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)
|
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)
|
6. Create organization, add users with org roles (owner + viewer)
|
||||||
7. Configure cameleer3-server OIDC (`rolesClaim: "roles"`, `audience`, `defaultRoles: ["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
|
- 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-saas` — SaaS app (frontend + JAR baked in)
|
||||||
- `cameleer-logto` — custom Logto with sign-in UI 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 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)
|
- `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)
|
- Design system: import from `@cameleer/design-system` (Gitea npm registry)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class ServerApiClient {
|
|||||||
.get()
|
.get()
|
||||||
.uri(uri)
|
.uri(uri)
|
||||||
.header("Authorization", "Bearer " + getAccessToken())
|
.header("Authorization", "Bearer " + getAccessToken())
|
||||||
.header("X-Cameleer-Protocol-Version", "2");
|
.header("X-Cameleer-Protocol-Version", "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized String getAccessToken() {
|
private synchronized String getAccessToken() {
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
spring:
|
spring:
|
||||||
jpa:
|
jpa:
|
||||||
show-sql: true
|
show-sql: false
|
||||||
|
|||||||
Reference in New Issue
Block a user