16 Commits

Author SHA1 Message Date
hsiegeln
5d04a154f9 refactor: deployment infrastructure cleanup (4 fixes)
Some checks failed
CI / build (push) Failing after 46s
CI / docker (push) Has been skipped
1. Docker socket security: remove root group from Dockerfile, use
   group_add in docker-compose.yml for runtime-only socket access

2. M2M server communication: create ServerApiClient using Logto
   client_credentials grant with API resource scope. Add M2M server
   role in bootstrap. Replace hacky admin/admin login in
   AgentStatusService.

3. Async deployment: extract DeploymentExecutor as separate @Service
   so Spring's @Async proxy works (self-invocation bypasses proxy).
   Deploy now returns immediately, health check runs in background.

4. Bootstrap: M2M server role (cameleer-m2m-server) with server:admin
   scope, idempotent creation outside the M2M app creation block.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 17:08:37 +02:00
hsiegeln
ca6e8ce35a fix: add cameleer user to root group for Docker socket access
The mounted /var/run/docker.sock is owned by root:root with rw-rw----
permissions. The cameleer user needs to be in the root group to
read/write the socket for building images and managing containers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:48:22 +02:00
hsiegeln
1a0f1e07be fix: JAR upload — increase multipart limit and fix storage permissions
Spring Boot defaults to 1MB max file size which rejected all JAR
uploads. Set to 200MB to match the configured max-jar-size. Also
create /data/jars with cameleer user ownership in the Dockerfile
so the non-root process can write uploaded JARs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:10:35 +02:00
hsiegeln
3ca13b6b88 perf: add BuildKit cache mounts for Maven and npm in Docker builds
Some checks failed
CI / build (push) Successful in 49s
CI / docker (push) Has been cancelled
Maven .m2 and npm caches persist across --no-cache builds, avoiding
full dependency re-downloads on every CI run.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 22:29:14 +02:00
hsiegeln
3fcbc431fb fix: restore multi-stage Dockerfiles, use cameleer-docker-builder
All checks were successful
CI / build (push) Successful in 1m8s
CI / docker (push) Successful in 39s
Follow cameleer3-server CI pattern: docker job uses
cameleer-docker-builder:1 (has Docker CLI), Dockerfiles contain
multi-stage builds (self-contained, no external toolchain needed).

- Dockerfile: restore frontend + maven + runtime stages
- ui/sign-in/Dockerfile: add node build stage + Logto base
- ci.yml: docker job reverts to cameleer-docker-builder:1,
  passes REGISTRY_TOKEN as build-arg, adds build cache

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 15:51:59 +02:00
hsiegeln
ad97a552f6 refactor: no builds in Dockerfiles, CI builds all artifacts
Some checks failed
CI / build (push) Successful in 59s
CI / docker (push) Failing after 11s
Dockerfiles now only COPY pre-built artifacts:
- Dockerfile (SaaS): just COPY target/*.jar, no multi-stage build
- ui/sign-in/Dockerfile (Logto): just FROM logto + COPY dist/
- Removed docker/logto.Dockerfile (had node build stage)

CI pipeline builds everything:
- docker job: builds frontend, JAR, sign-in UI, then packages
  into images using the simple Dockerfiles
- Uses cameleer-build:1 (has node + maven + docker)
- build job: also builds sign-in UI for testing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 15:39:19 +02:00
hsiegeln
972f9b5f38 feat: custom Logto image + auto-redirect to sign-in
All checks were successful
CI / build (push) Successful in 39s
CI / docker (push) Successful in 40s
- Add docker/logto.Dockerfile: builds custom Logto image with sign-in
  UI baked into /etc/logto/packages/experience/dist/
- Remove sign-in-ui init container, signinui volume, CUSTOM_UI_PATH
  (CUSTOM_UI_PATH is Logto Cloud only, not available in OSS)
- Remove sign-in build stage from SaaS Dockerfile (now in logto.Dockerfile)
- Remove docker/saas-entrypoint.sh (no longer needed)
- LoginPage auto-redirects to Logto OIDC on mount instead of showing
  "Sign in with Logto" button — seamless sign-in experience

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 15:12:11 +02:00
hsiegeln
9013740b83 fix: mount custom sign-in UI over Logto experience dist
All checks were successful
CI / build (push) Successful in 39s
CI / docker (push) Successful in 33s
CUSTOM_UI_PATH is a Logto Cloud feature, not available in OSS.
The correct approach for self-hosted Logto is to volume-mount
over /etc/logto/packages/experience/dist/.

- Use init container (sign-in-ui) to copy dist to shared volume
  as root (fixes permission denied with cameleer user)
- Logto mounts signinui volume at experience/dist path
- Logto depends on sign-in-ui init container completion
- Remove saas-entrypoint.sh approach (no longer needed)
- Revert Dockerfile entrypoint to direct java -jar
- Permit /favicon.svg in SecurityConfig for sign-in page logo

Tested: full OIDC flow works end-to-end via Playwright.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 14:24:33 +02:00
hsiegeln
df220bc5f3 feat: custom Logto sign-in UI with Cameleer branding
All checks were successful
CI / build (push) Successful in 40s
CI / docker (push) Successful in 50s
Replace Logto's default sign-in page with a custom React SPA that
matches the cameleer3-server login page using @cameleer/design-system.

- New Vite+React app at ui/sign-in/ with Experience API integration
- 4-step auth flow: init → verify password → identify → submit
- Design-system components: Card, Input, Button, FormField, Alert
- Same witty random subtitles as cameleer3-server LoginPage
- Dockerfile: add sign-in-frontend build stage, copy dist to image
- docker-compose: CUSTOM_UI_PATH on Logto, shared signinui volume
- SaaS entrypoint copies sign-in dist to shared volume on startup
- Add .gitattributes for LF line endings

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 11:43:22 +02:00
hsiegeln
ad6805e447 fix: use standard dist/ output for Vite, copy to static/ explicitly
All checks were successful
CI / build (push) Successful in 39s
CI / docker (push) Successful in 37s
The relative outDir '../src/main/resources/static' resolved
unpredictably in Docker. Use standard 'dist/' output, then:
- Dockerfile: COPY --from=frontend /ui/dist/ to static/
- CI: cp -r dist/ to src/main/resources/static/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 23:44:50 +02:00
hsiegeln
aaa4af40c5 fix: use BUILDPLATFORM for native cross-compilation, remove broken cache mounts
Some checks failed
CI / build (push) Successful in 42s
CI / docker (push) Has been cancelled
Build and frontend stages now use --platform=$BUILDPLATFORM so Maven and
Node run natively on the ARM64 CI runner instead of under QEMU emulation.
Only the final JRE runtime stage targets amd64. Removed --mount=type=cache
which doesn't persist across CI runs with buildx --push; the registry layer
cache (--cache-from/--cache-to in CI) handles caching the dependency layer.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:31:22 +02:00
hsiegeln
c4a4c9d2fc fix: cross-compile Docker image for amd64 and add npm registry auth
Some checks failed
CI / build (push) Successful in 40s
CI / docker (push) Has been cancelled
- CI docker job: QEMU + buildx + --platform linux/amd64 (runners are arm64)
- Dockerfile: REGISTRY_TOKEN build arg for @cameleer/design-system npm auth
- CI build job: npm auth token for frontend build step
- Registry cache for faster builds

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:21:44 +02:00
hsiegeln
e325c4d2c0 fix: correct Dockerfile frontend build output path
All checks were successful
CI / build (push) Successful in 1m10s
CI / build (pull_request) Successful in 1m9s
CI / docker (pull_request) Has been skipped
CI / docker (push) Successful in 23s
Vite's outDir is '../src/main/resources/static' (relative to ui/),
which resolves to /src/main/resources/static/ in the Docker build.
The COPY was looking at /ui/dist/ which doesn't exist.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:10:42 +02:00
hsiegeln
4c8c8efbe5 feat: add SPA controller, Traefik route, CI frontend build, and HOWTO update
Some checks failed
CI / build (push) Successful in 49s
CI / docker (push) Failing after 38s
CI / build (pull_request) Successful in 1m2s
CI / docker (pull_request) Has been skipped
- SpaController catch-all forwards non-API routes to index.html
- Traefik SPA route at priority=1 catches all unmatched paths
- CI pipeline builds frontend before Maven
- Dockerfile adds multi-stage frontend build
- HOWTO.md documents frontend development workflow

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:06:36 +02:00
hsiegeln
d81ce2b697 ci: revert artifact approach, use BuildKit cache for Maven deps
All checks were successful
CI / build (push) Successful in 29s
CI / docker (push) Successful in 2m31s
Gitea Actions doesn't support upload/download-artifact v4.
Reverted to two-job approach (git clone + docker build).
Added BuildKit cache mount (--mount=type=cache,target=/root/.m2)
to Dockerfile so Maven deps persist across Docker builds on the
same runner. First build downloads, subsequent builds are cached.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 19:27:08 +02:00
hsiegeln
fcb372023f feat: add Dockerfile and Gitea Actions CI pipeline
Some checks failed
CI / build (push) Failing after 32s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 10:33:01 +02:00