From 1ed2d3a61147d9137db9248ea10a800de006826f Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Mon, 20 Apr 2026 15:52:24 +0200 Subject: [PATCH] chore(docker): full-stack docker-compose mirroring deploy/ k8s manifests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors the k8s manifests in deploy/ as a local dev stack: - cameleer-postgres (matches deploy/cameleer-postgres.yaml) - cameleer-clickhouse (matches deploy/cameleer-clickhouse.yaml, default CLICKHOUSE_DB=cameleer) - cameleer-server (built from Dockerfile, env mirrors deploy/base/server.yaml) - cameleer-ui (built from ui/Dockerfile, served on host :8080 to leave :5173 free for Vite dev) Dockerfile + ui/Dockerfile: REGISTRY_TOKEN is now optional (empty → skip Maven/npm auth). cameleer-common package is public, so anonymous pulls succeed; private packages still require the token. Backend defaults tuned for local E2E: - RUNTIME_ENABLED=false (no Docker-in-Docker deployments in dev stack) - OUTBOUND_HTTP_ALLOW_PRIVATE_TARGETS=true (so webhook tests can target host.docker.internal etc.) - UIUSER/UIPASSWORD=admin/admin (matches Playwright E2E_ADMIN_USER/PASS defaults) - CORS includes both :5173 (Vite) and :8080 (nginx) --- Dockerfile | 12 +++-- docker-compose.yml | 123 ++++++++++++++++++++++++++++++++++++++++++++- ui/Dockerfile | 10 ++-- 3 files changed, 137 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index aebfba83..3336cbf0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,14 @@ FROM --platform=$BUILDPLATFORM maven:3.9-eclipse-temurin-17 AS build WORKDIR /build -# Configure Gitea Maven Registry for cameleer-common dependency -ARG REGISTRY_TOKEN -RUN mkdir -p ~/.m2 && \ - echo 'giteacameleer'${REGISTRY_TOKEN}'' > ~/.m2/settings.xml +# Optional auth for Gitea Maven Registry. The `cameleer/cameleer-common` package +# is published publicly, so empty token → anonymous pull (no settings.xml). +# Private packages require a non-empty token. +ARG REGISTRY_TOKEN="" +RUN if [ -n "$REGISTRY_TOKEN" ]; then \ + mkdir -p ~/.m2 && \ + printf 'giteacameleer%s\n' "$REGISTRY_TOKEN" > ~/.m2/settings.xml; \ + fi COPY pom.xml . COPY cameleer-server-core/pom.xml cameleer-server-core/ diff --git a/docker-compose.yml b/docker-compose.yml index 5439cb51..2b4420da 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,24 @@ +## +## Local development + E2E stack. Mirrors the k8s manifests in deploy/ : +## - cameleer-postgres (PG for RBAC/config/audit/alerting — Flyway migrates on server start) +## - cameleer-clickhouse (OLAP for executions/logs/metrics/stats/diagrams) +## - cameleer-server (Spring Boot backend; built from this repo's Dockerfile) +## - cameleer-ui (nginx-served SPA; built from ui/Dockerfile) +## +## Usage: +## docker compose up -d --build # full stack, detached +## docker compose up -d cameleer-postgres cameleer-clickhouse # infra only (dev via mvn/vite) +## docker compose down -v # stop + remove volumes +## +## Defaults match `application.yml` and the k8s base manifests. Production +## k8s still owns the source of truth; this compose is for local iteration +## and Playwright E2E. Secrets are non-sensitive dev placeholders. +## + services: cameleer-postgres: image: postgres:16 + container_name: cameleer-postgres ports: - "5432:5432" environment: @@ -8,7 +26,110 @@ services: POSTGRES_USER: cameleer POSTGRES_PASSWORD: cameleer_dev volumes: - - cameleer-pgdata:/home/postgres/pgdata/data + - cameleer-pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U cameleer -d cameleer"] + interval: 5s + timeout: 3s + retries: 20 + restart: unless-stopped + + cameleer-clickhouse: + image: clickhouse/clickhouse-server:24.12 + container_name: cameleer-clickhouse + ports: + - "8123:8123" + - "9000:9000" + environment: + CLICKHOUSE_DB: cameleer + CLICKHOUSE_USER: default + CLICKHOUSE_PASSWORD: "" + # Allow the default user to manage access (matches k8s StatefulSet env) + CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: "1" + ulimits: + nofile: + soft: 262144 + hard: 262144 + volumes: + - cameleer-chdata:/var/lib/clickhouse + healthcheck: + # wget-less image: use clickhouse-client's ping equivalent + test: ["CMD-SHELL", "clickhouse-client --query 'SELECT 1' || exit 1"] + interval: 5s + timeout: 3s + retries: 20 + restart: unless-stopped + + cameleer-server: + build: + context: . + dockerfile: Dockerfile + args: + # Public cameleer-common package — token optional. Override with + # REGISTRY_TOKEN=... in the shell env if you need a private package. + REGISTRY_TOKEN: ${REGISTRY_TOKEN:-} + container_name: cameleer-server + ports: + - "8081:8081" + environment: + SPRING_DATASOURCE_URL: jdbc:postgresql://cameleer-postgres:5432/cameleer?currentSchema=tenant_default&ApplicationName=tenant_default + SPRING_DATASOURCE_USERNAME: cameleer + SPRING_DATASOURCE_PASSWORD: cameleer_dev + SPRING_FLYWAY_USER: cameleer + SPRING_FLYWAY_PASSWORD: cameleer_dev + CAMELEER_SERVER_CLICKHOUSE_URL: jdbc:clickhouse://cameleer-clickhouse:8123/cameleer + CAMELEER_SERVER_CLICKHOUSE_USERNAME: default + CAMELEER_SERVER_CLICKHOUSE_PASSWORD: "" + # Auth / UI credentials — dev defaults; change before exposing the port. + CAMELEER_SERVER_SECURITY_UIUSER: admin + CAMELEER_SERVER_SECURITY_UIPASSWORD: admin + CAMELEER_SERVER_SECURITY_UIORIGIN: http://localhost:5173 + CAMELEER_SERVER_SECURITY_CORSALLOWEDORIGINS: http://localhost:5173,http://localhost:8080 + CAMELEER_SERVER_SECURITY_BOOTSTRAPTOKEN: dev-bootstrap-token-for-local-agent-registration + CAMELEER_SERVER_SECURITY_JWTSECRET: dev-jwt-secret-32-bytes-min-0123456789abcdef0123456789abcdef + # Runtime (Docker-in-Docker deployment) disabled for local stack + CAMELEER_SERVER_RUNTIME_ENABLED: "false" + CAMELEER_SERVER_TENANT_ID: default + # SSRF guard: allow private targets for dev (Playwright + local webhooks) + CAMELEER_SERVER_OUTBOUND_HTTP_ALLOW_PRIVATE_TARGETS: "true" + depends_on: + cameleer-postgres: + condition: service_healthy + cameleer-clickhouse: + condition: service_healthy + healthcheck: + # JRE image has wget; /api/v1/health is Actuator + Spring managed endpoint + test: ["CMD-SHELL", "wget -qO- http://localhost:8081/api/v1/health > /dev/null || exit 1"] + interval: 10s + timeout: 5s + retries: 12 + start_period: 90s + restart: unless-stopped + + cameleer-ui: + build: + context: ./ui + dockerfile: Dockerfile + args: + REGISTRY_TOKEN: ${REGISTRY_TOKEN:-} + container_name: cameleer-ui + # Host :8080 — Vite dev server (npm run dev:local) keeps :5173 for local iteration. + ports: + - "8080:80" + environment: + # nginx proxies /api → CAMELEER_API_URL + CAMELEER_API_URL: http://cameleer-server:8081 + BASE_PATH: / + depends_on: + cameleer-server: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://localhost/healthz > /dev/null || exit 1"] + interval: 5s + timeout: 3s + retries: 10 + restart: unless-stopped volumes: cameleer-pgdata: + cameleer-chdata: diff --git a/ui/Dockerfile b/ui/Dockerfile index 132afbe9..a7bd7ada 100644 --- a/ui/Dockerfile +++ b/ui/Dockerfile @@ -1,15 +1,19 @@ FROM --platform=$BUILDPLATFORM node:22-alpine AS build WORKDIR /app -ARG REGISTRY_TOKEN +ARG REGISTRY_TOKEN="" COPY package.json package-lock.json .npmrc ./ -RUN echo "//gitea.siegeln.net/api/packages/cameleer/npm/:_authToken=${REGISTRY_TOKEN}" >> .npmrc && \ +RUN if [ -n "$REGISTRY_TOKEN" ]; then \ + echo "//gitea.siegeln.net/api/packages/cameleer/npm/:_authToken=${REGISTRY_TOKEN}" >> .npmrc; \ + fi && \ npm ci COPY . . # Upgrade design system to latest dev snapshot (after COPY to bust Docker cache) -RUN echo "//gitea.siegeln.net/api/packages/cameleer/npm/:_authToken=${REGISTRY_TOKEN}" >> .npmrc && \ +RUN if [ -n "$REGISTRY_TOKEN" ]; then \ + echo "//gitea.siegeln.net/api/packages/cameleer/npm/:_authToken=${REGISTRY_TOKEN}" >> .npmrc; \ + fi && \ npm install @cameleer/design-system@dev && \ rm -f .npmrc