Route k3s registry mirrors through harbor-core ClusterIP with hostname-only auth keys, use HTTP EXT_ENDPOINT so OAuth tokens work on port 80, extend deploy readiness timeout, and harden Kaniko build/dockerfile fallbacks.
Co-authored-by: Cursor <cursoragent@cursor.com>
Rework the application build/deploy pipeline for scalability, reproducibility,
and security:
- Build queue: deploys run through a bounded-concurrency Bull queue
(BUILD_CONCURRENCY, default 3) so concurrent user deploys can't flood the
cluster with Kaniko jobs. Build state (progress / cancel / session) moves from
in-memory Maps to Redis, so cancel + live logs work across backend replicas.
- Nixpacks + BYO Dockerfile: code runtimes build via Nixpacks (or the user's own
Dockerfile when present); the hand-written per-runtime Dockerfile generators
and runtime auto-detection are removed. WordPress keeps its templated path.
Build-time mirror env (NIXPACKS_BUILD_ENV) supports the Iran network.
- Source upload to MinIO: archives stream to in-cluster MinIO; build pods pull
via a presigned URL. Removes the PVC + helper pod + kubectl cp upload path.
- Report-only Trivy scan after build; per-severity summary stored on the
deployment and shown as a badge in the dashboard. Never gates a deploy.
- Registry GC: a Redis-locked daily job keeps the newest N image tags per app
(REGISTRY_KEEP_VERSIONS, default 3) and reclaims disk via garbage-collect.
- Hardening: git tokens are delivered via a per-build Secret + git credential
store instead of being embedded in the clone URL / Job manifest; build timeout
is configurable.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the admin-only "cluster assignment" UI from the resources &
config step of the deploy wizard and the related backend override.
App placement is now always decided automatically by the allocator.
- frontend: remove cluster/pool selection block, review-step cluster
row, clusterMode state, public cluster/pool queries, and clusterId/
poolId from CreateApplicationDto
- backend: drop clusterId/poolId override from the create DTO and
simplify ApplicationsService.create to always auto-allocate; widen
selectClusterForApplication param to keep the fallback path working
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ingress / preview URLs:
- Default the app Ingress class and ACME HTTP-01 solver to Traefik
(k3s default) via a new INGRESS_CLASS env, instead of hardcoding nginx —
fixes 404s on clusters without ingress-nginx.
- Only put public, real-TLD hosts (custom domain + preview) in the TLS
block; the internal *.apps.cloudhost.local host no longer poisons the
Let's Encrypt order, so certs actually issue.
- Make the per-app preview number stable across redeploys so URLs stop
breaking, and let PREVIEW_BASE_DOMAIN configure the base domain.
Registry pulls:
- Point the k3s registries.yaml mirror endpoint at the registry NodePort on
loopback so node containerd never depends on cluster DNS (image pulls
survive node restarts).
Builds:
- Pin the Kaniko image, use IfNotPresent pull policy, drop the dead build
queue/processor, and retry transient Kubernetes API errors while polling
build jobs.
Logs & apps list:
- fluent-bit reads log files from head so startup output reaches
Elasticsearch.
- Order joined deployments newest-first so the apps list shows the latest
deployment status.
Allocation:
- Reserve in-flight (pending/building) capacity and stop globally degrading
the cluster on a single allocation failure, so concurrent deploys don't
starve or wrongly report "no healthy cluster".
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Introduce a catalog-driven Tools Management section under Clusters so
admins can install/uninstall infrastructure tools per cluster: cert-manager
(Helm/jetstack), ClusterIssuer (email + HTTP01 form, depends on cert-manager),
and central Elasticsearch. Cluster creation no longer auto-installs Elastic
or the cloudhost-node-cluster-dns DaemonSet; build bootstrap stays automatic.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bootstrap configures systemd-resolved for *.cluster.local, installs k3s registries.yaml for the internal registry only, removes the legacy external-registry DaemonSet, and aligns Helm REGISTRY_PULL_URL with the in-cluster registry URL.
Co-authored-by: Cursor <cursoragent@cursor.com>
Remove external registry Ingress (repo.3fase.ir) and route Kaniko push and app pulls through the internal ClusterIP registry. Add RegistryService, ensure StorageClass and pull secrets on deploy, make Elasticsearch install/repair more resilient, and add per-cluster Deploy Elastic controls in admin UI.
Co-authored-by: Cursor <cursoragent@cursor.com>
Deploy cloudhost-logging on cluster registration, ship app and optional service logs to ES with owner isolation, and fix Kibana 8.12 auth via kibana_system.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Add POST /users endpoint for admin to create users with hashed passwords
- Add GET /users?search= with ILike search on email/firstName/lastName
- Add PATCH /users/:id/role for role assignment (user/admin)
- Return appCount per user in the users list
- Add GET /clusters/:id/resources for node, CPU, memory, pod monitoring
- Parse K8s node capacity/allocatable with CPU millicores and memory MiB helpers
- Frontend: admin users page with search bar, create form, role dropdown, app count
- Frontend: cluster resource panel with nodes table, CPU/memory bars, summary cards
- Add ClusterPool entity for grouping clusters into named pools
- Support 3 deployment modes: manual cluster, pool load-balanced, default fallback
- Pool strategies: least-apps (fewest deployed apps) and round-robin
- Add pool CRUD API endpoints (admin) and public pool listing
- Frontend deploy page: 3-mode cluster selector (Default/Manual/Pool)
- Frontend app detail: shows assigned cluster and pool info
- Admin pools management page with cluster selection and strategy picker
- Application entity extended with poolId field