Cozystack is a free PaaS platform and framework for building private clouds and providing users/customers with managed Kubernetes, KubeVirt-based VMs, databases as a service, NATS, message brokers, etc. with GPU support in VMs and Kubernetes clusters.
Cozystack v1.3.0
Cozystack v1.3.0 brings storage-aware pod scheduling via a LINSTOR scheduler extender, a managed LINSTOR GUI web console with Keycloak SSO, a curated VM Default Images catalog for out-of-the-box virtual-machine provisioning, a new WorkloadsReady / Events observability surface with S3 bucket metering, and cross-namespace VMInstance backup restore with a full RestoreJob dashboard flow. The release also ships stricter tenant-name validation, VMInstance network-selector improvements, Keycloak theme injection and SMTP configuration, a host-runtime preflight check, and rolls up every fix from the v1.2.1 → v1.2.4 patch line.
Note: Items marked (backported to v1.2.x) were also shipped in v1.2.1, v1.2.2, v1.2.3, or v1.2.4 patch releases.
Feature Highlights
Storage-Aware Scheduling via the LINSTOR Extender
The cozystack-scheduler now calls a LINSTOR scheduler extender for storage-locality-aware pod placement. When a pod declares both a SchedulingClass and LINSTOR-backed PVCs, the scheduler consults LINSTOR to prefer nodes where volume replicas already exist — reducing cross-node replication traffic and improving I/O latency for storage-heavy workloads such as databases, object stores, and VMs.
The integration builds on the existing SchedulingClass tenant workload placement system introduced in v1.2.0 and requires no tenant-side configuration — workloads simply benefit once a SchedulingClass is assigned. Administrators can mix storage locality with the existing data-center / hardware-generation constraints defined on SchedulingClass CRs (@lllamnyp in #2330).
LINSTOR GUI: Managed Web Console for Storage Administration
A new opt-in linstor-gui system package deploys LINBIT's linstor-gui web UI alongside the LINSTOR controller with mTLS client authentication, non-root security context, and a ClusterIP-only service by default. When OIDC is configured on the platform, an optional Keycloak-protected Ingress (via oauth2-proxy) exposes the UI for browser access. Access is restricted to members of the cozystack-cluster-admin Keycloak group, consistent with host-cluster admin RBAC, and the gatekeeper blocks in-app LINSTOR authentication setup at the nginx proxy layer so the managed configuration cannot be subverted through the UI.
Operators who prefer CLI access keep the existing linstor command; the GUI is strictly additive and stays disabled by default (@myasnikovdaniil in #2382, #2390, #2415, #2419).
VM Default Images: Out-of-the-Box VM Provisioning
The new vm-default-images package provides a curated set of cluster-wide virtual-machine images (Ubuntu, Debian, CentOS Stream, and others) as pre-populated DataVolumes, so tenants can provision VMs against well-known base images without first having to upload them. The package is opt-in via the iaas bundle and defaults to replicated storage for high availability. Migration 38 renames legacy vm-image-* DataVolumes to the new vm-default-images-* naming scheme, and the vm-disk chart gains a new "disk" source type for cloning from existing vm-disks in the same namespace (@myasnikovdaniil in #2258).
Application Observability: WorkloadsReady, Events, and S3 Bucket Metering
Applications now expose a WorkloadsReady condition on their status by querying associated WorkloadMonitor resources, giving operators a single place to check whether all underlying workloads (Deployments, StatefulSets, DaemonSets, PVCs) are healthy. The dashboard gains a new Events tab showing namespace-scoped Kubernetes events per application, with fallback to .firstTimestamp when .eventTime is absent. A long-standing bug where WorkloadMonitor's Operational status was never persisted is fixed in the same change (@lexfrei in #2356).
The WorkloadMonitor reconciler is extended to track COSI BucketClaim objects as first-class Workloads, and the bucket controller now queries SeaweedFS logical and physical bucket-size metrics from VictoriaMetrics via a namespace-scoped monitoring endpoint, enabling S3 billing integration on par with Pods and PVCs (@kitsunoff in #2391). Workloads are also enriched with workloads.cozystack.io/resource-preset and source-object labels so downstream billing pipelines can correlate monitors with the tenant preset that produced them (@androndo in #2416).
Cross-Namespace VM Backup Restore and RestoreJob Dashboard
The backup system now supports restoring VMInstance backups into a different namespace (cross-namespace copy restores) with IP/MAC preservation and safe rename semantics. In-place backup and restore flows for VMDisk and VMInstance are improved: HelmReleases and DataVolumes are properly handled, and Velero failure messages are propagated to the Application status. The backup status structure has been refactored to store underlying resources as a generic opaque JSON object, enabling arbitrary application-specific metadata without status-schema churn (@androndo in #2251, #2319, #2329).
The dashboard now ships a complete RestoreJob experience: list view, details page, create form, and sidebar entry, with a "Same as backup" fallback rendering when spec.targetApplicationRef is omitted. Non-CRD-backed sidebar factories (kube-*, plan, backupjob, backup, restorejob) are marked static so they pick up consistent managed-by labels across reconciles (@myasnikovdaniil in #2437).
Major Features and Improvements
-
[api] Reject tenant names with dashes at Create time: Enforces alphanumeric-only naming for Tenants at the API level, preventing names with hyphens that would silently fail during Helm reconciliation. A corresponding regex tightening and regression test suite hardens the validation (@lexfrei in #2380).
-
[platform] Validate computed tenant namespace length: Rejects Tenant creation when the computed ancestor-chain namespace would exceed the 63-character Kubernetes namespace limit, preventing opaque HelmRelease reconcile errors downstream (@lexfrei in #2376).
-
[vm-instance] Rename subnets to networks and add dropdown selector: Renames the misleading subnets field to networks in VMInstance for clarity, adds a dropdown selector for available networks in the dashboard form, and includes migration 36 to copy existing subnets values. The old field remains supported for backward compatibility (@sircthulhu in #2263).
-
[keycloak] Enable injecting themes: Cozystack administrators can now inject custom Keycloak themes via initContainers for UI white-labeling and customization (@lllamnyp in #2142).
-
[keycloak-configure] Add email verification and SMTP configuration: Adds configurable Keycloak settings for user self-registration, email verification, and SMTP server configuration, enabling automated user onboarding flows (@BROngineer in #2318).
-
[postgres] Pin system PostgreSQL to 17.7-standard-trixie: Pins the PostgreSQL image for system databases (Grafana, Alerta, Harbor, Keycloak, SeaweedFS) to 17.7-standard-trixie across chart templates and values.yaml, and ships migration 37 to patch existing CNPG Cluster imageName fields to the same variant (handling unset, any PG 17 tag, and bare-version tags). This prevents CNPG from defaulting to PostgreSQL 18 and locks system databases to the trixie variant consistent with the monitoring stack requirements (related backports shipped in v1.2.1 via #2309 and v1.2.2 via #2364) (@myasnikovdaniil in #2369).
-
[platform] Prevent installed packages deletion: Adds the helm.sh/resource-policy: keep annotation to platform packages so disabling a package no longer triggers automatic Helm deletion, restoring the documented behavior where operators must explicitly delete a package (backported to v1.2.1) (@kvaps in #2273).
-
[mariadb] Always enable replication for consistent service naming: MariaDB now always enables replication, creating -primary/-secondary services even for single-replica instances. This fixes dashboard visibility and backup functionality for single-replica setups (@sircthulhu in #2279).
-
[hack] Add host runtime preflight check: New check-host-runtime.sh script and make preflight target that warns operators when a standalone containerd or docker runtime is running alongside the embedded k3s runtime, helping diagnose container-runtime conflicts early in an installation (@lexfrei in #2371).
-
[hack] Add check-readiness.sh diagnostic script: A new diagnostic script for tracking platform reconciliation by checking readiness of Packages, ArtifactGenerators, ExternalArtifacts, and HelmReleases, with support for watch mode and continuous monitoring (@myasnikovdaniil in #2294).
-
[platform] Add resourcePreset labels to WorkloadMonitor labels: WorkloadMonitor labels with the workloads.cozystack.io/ prefix are now propagated onto created Workloads; created Workloads always include the reserved workloads.cozystack.io/monitor label, and Helm app charts add workloads.cozystack.io/resource-preset metadata to WorkloadMonitor manifests, enabling downstream billing pipelines to correlate monitors with the tenant preset that produced them (@androndo in #2416).
Bug Fixes
-
[platform] Migrate ACME HTTP-01 to ingressClassName API: Switches ACME HTTP-01 issuance from the deprecated acme.cert-manager.io/http01-ingress-class annotation to the modern ingressClassName field on ClusterIssuer and solver pods. Previously, ClusterIssuers referenced a non-existent nginx class while each Ingress individually overrode it via annotation — producing ingressClassName and class cannot be set at the same time errors when tenants attempted to migrate to the modern field. The migration is atomic: both the ClusterIssuer and consuming Ingresses are updated together (backported to v1.2.4) (@myasnikovdaniil in #2436).
-
[harbor] Remove incorrect tenant module flags: Harbor is a PaaS service, not a tenant module. Incorrect spec.dashboard.module: true and internal.cozystack.io/tenantmodule flags caused Harbor to appear in the sidebar "Modules" section and be misclassified by controllers handling tenant modules. The flags are now removed so Harbor is displayed in its proper PaaS category and is no longer treated as a tenant-scoped HelmRelease (@kvaps in #2444).
-
[kube-ovn] Resolve kubeovn-plunger RBAC forbidden on deployments: Grants kube-ovn-plunger the RBAC needed to list Deployments so it can reconcile ovn-central, fixing deployments.apps is forbidden errors in cozy-kubeovn (@kvaps in #2441).
-
[cilium] Opt-out of cri-containerd.apparmor.d for nsenter init containers: Opts cilium-agent init containers out of the cri-containerd.apparmor.d AppArmor profile on non-Talos variants (cilium-generic, kubeovn-cilium-generic), fixing Init:CrashLoopBackOff on Ubuntu 22.04+ and Debian where the profile denies nsenter namespace entry. Talos variants are untouched as Talos does not load the AppArmor LSM (backported to v1.2.2) (@lexfrei in #2370).
-
[virtual-machine] Exclude external VM services from Cilium BPF LB: Adds the service.kubernetes.io/service-proxy-name: cozy-proxy label to VM LoadBalancer services with external: true, telling Cilium to skip BPF processing entirely. Fixes inter-tenant connectivity via public LB IPs (Cilium's DNAT caused cross-tenant pod-to-pod flow classification, triggering CiliumClusterwideNetworkPolicy blocks) and restores WholeIP behavior on Cilium 1.19+ where wildcard service drop entries previously blocked traffic to LB IPs on undeclared ports (backported to v1.2.2) (@mattia-eleuteri in #2357).
-
[monitoring] Fix infra dashboards missing in default variant: Includes the cozy-monitoring namespace in the dashboard rendering condition, fixing infrastructure Grafana dashboards not rendering in the default platform variant (only the tenant-root namespace was previously checked) (backported to v1.2.2) (@mattia-eleuteri in #2365).
-
[build] Filter git describe to match only v tags*: Adds --match 'v*' to all git describe calls in hack/common-envs.mk, preventing the api/apps/v1alpha1/vX.Y.Z subtag from being picked up instead of the release tag and producing invalid Docker image tags (backported to v1.2.2) (@kvaps in #2386).
-
[platform] Fix resource allocation ratios not propagated to packages: Restores propagation of cpuAllocationRatio, memoryAllocationRatio, and ephemeralStorageAllocationRatio from platform/values.yaml to the cozystack-values Secret that managed applications and KubeVirt read, fixing a regression introduced in the bundle restructure that silently ignored operator-configured ratios (backported to v1.2.1) (@sircthulhu in #2296).
-
[kubernetes] Set explicit ephemeral-storage on virt-launcher pods: Sets explicit domain.resources ephemeral-storage on the VirtualMachine spec to prevent virt-launcher pods from being evicted because LimitRange defaults were too small for the actual emptyDisk capacity (backported to v1.2.3) (@kvaps in #2317).
-
[multus] Pin master CNI to 05-cilium.conflist: Prevents a boot-time race where multus could auto-detect kube-ovn's conflist instead of Cilium's, which would cause pods to bypass the Cilium chain entirely and lose their endpoint (backported to v1.2.1) (@kvaps in #2315).
-
[multus] Build custom image with DEL cache fix: Fixes sandbox cleanup deadlock when CNI ADD never completes, preventing stale sandbox name reservations from permanently blocking pod creation after a node disruption (backported to v1.2.1) (@kvaps in #2313).
-
[linstor] Set verify-alg to crc32c: Prevents DRBD connection failures on kernels where crct10dif is unavailable (e.g., Talos v1.12.6 with kernel 6.18.18) by setting the LINSTOR verify-alg controller default to crc32c (backported to v1.2.1) (@kvaps in #2303).
-
[linstor] Preserve TCP ports during toggle-disk operations: Saves existing TCP ports into the LayerPayload before removeLayerData() deletes them, preventing DRBD resources from entering StandAlone state when a satellite misses the resulting update (backported to v1.2.1) (@kvaps in #2292).
-
[linstor] Increase satellite startup probe failure threshold: Raises the LINSTOR satellite startupProbe failureThreshold from 3 to 30 (30s → 300s) in the LinstorSatelliteConfiguration pod template, giving satellites with slow storage initialization enough time to come up without being killed and restarted (@Arsolitt in #2425).
Security
-
docs: add SECURITY.md: Adds vulnerability reporting procedures, disclosure expectations, and supported release lines (@kvaps in #2230).
-
docs: add OpenSSF Best Practices badge to README: Adds the OpenSSF Best Practices passing badge to the project README (@lexfrei in #2320).
Dependencies & Version Updates
-
[kube-ovn] Bump kube-ovn to v1.15.10 with port-group regression fix: Updates packages/system/kubeovn to upstream v1.15.10 (from v1.15.3) and carries a patch for pkg/controller/pod.go that preserves a VM LSP's port-group memberships when Kubernetes GCs a completed virt-launcher pod while another virt-launcher pod of the same VM is still running. Without the patch, the destination pod of a successful live migration lost its security groups, network policies, and node-scoped routing until kube-ovn-controller was restarted (@kvaps in #2443).
-
[monitoring] Upgrade victoria-metrics-operator to v0.68.4: Bumps the vendored victoria-metrics-operator Helm chart from 0.59.1 to 0.61.0 (operator appVersion v0.68.1 → v0.68.4), picking up upstream fixes for VMPodScrape port routing on VMAgent/VLAgent and StatefulSet pod deletion (not eviction) when maxUnavailable=100% (@lexfrei in #2426).
-
[linstor] Update piraeus-server to v1.33.2 with selected backports: Bumps LINSTOR server from v1.33.1 to v1.33.2 with backported patches for stale bitmap adjust retry, LUKS2 header sizing, optimal I/O size detection, and the maintainer implementation. All patches verified against upstream v1.33.2 with git apply --check and gradlew compileJava (backported to v1.2.2) (@kvaps in #2331).
-
[kamaji] Update to 26.3.5-edge, drop upstreamed patches: Updates Kamaji from edge-26.2.4 to 26.3.5-edge and removes two patches accepted upstream. Adds configurable probe tuning and DataStore readiness conditions (@myasnikovdaniil in #2260).
-
[talm] Release v0.23.0, v0.23.1, v0.24.0 (github.com/cozystack/talm): Migrates to the Talos v1.12 multi-document machine config format (@lexfrei in cozystack/talm#116); renders templates online in apply to resolve lookups (@myasnikovdaniil in cozystack/talm#119); bumps dependencies and modernizes the codebase (@lexfrei in cozystack/talm#124).
-
[ansible-cozystack] Release v1.2.1, v1.2.2, v1.2.4 (github.com/cozystack/ansible-cozystack): Exposes publishing.externalIPs and tenant-root ingress via role variables (@lexfrei in cozystack/ansible-cozystack#30); adds a comprehensive node prerequisites audit (@lexfrei in cozystack/ansible-cozystack#27); replaces ansible.utils.ipaddr with a stdlib-based test plugin (@lexfrei in cozystack/ansible-cozystack#24); adds v prefix to collection version in requirements.yml examples (@lexfrei in cozystack/ansible-cozystack#23); tracks installer releases v1.2.1 through v1.2.4 (@app/renovate in cozystack/ansible-cozystack#20, #22, #29, #31, #32).
Development, Testing, and CI/CD
-
[ci] Replace cozystack-bot PAT with cozystack-ci GitHub App: Replaces the long-lived cozystack-bot personal access token with short-lived, scoped tokens from the cozystack-ci GitHub App across all release workflows (tags.yaml, auto-release.yaml, pull-requests-release.yaml), improving security and auditability of CI operations (@tym83 in #2351; @kvaps in #2383, #2392).
-
[ci] Add Gemini Code Assist and CodeRabbit configuration: Adds repository-level configuration for AI code reviewers with ignore patterns for vendored/generated code and incremental review settings (@lexfrei in #2385).
-
[ci] Promote next/ trunk on new minor/major releases: Updates update-website-docs in tags.yaml to match the new docs-versioning contract — the website repo replaces the old "pre-create vX.Y/ draft directory" scheme with a permanent content/en/docs/next/ trunk, and released version directories are promoted explicitly by the release workflow (@myasnikovdaniil in #2433).
-
[tests] Fix Kafka E2E test timeout and retry race condition: Increases Kafka E2E test timeout from 60s to 300s and fixes a retry race where kubectl apply could hit a still-deleting resource (@lexfrei in #2358).
-
docs: adopt Conventional Commits for commit and PR titles: Standardizes commit and PR title format to type(scope): description across all contributing docs and the PR template (@lexfrei in #2395).
-
docs(ci): require screenshots for UI changes in PR template: Adds a mandatory screenshots section to the PR template for UI-related changes (@kitsunoff in #2407).
-
chore(maintenance): add @myasnikovdaniil to CODEOWNERS: Adds @myasnikovdaniil to the default owners in .github/CODEOWNERS for automatic review requests (@myasnikovdaniil in #2434).
Documentation
-
[website] Add ApplicationDefinition naming convention reference: Documents how cozystack-api resolves kinds to their backing definitions (@lexfrei in cozystack/website#478).
-
[website] Document Talos / talosctl / Cozystack version pairing: Adds a version compatibility matrix for installation (@lexfrei in cozystack/website#484).
-
[website] Document namespace layout and parent/child derivation: Explains tenant namespace hierarchy and parent/child namespace derivation rules (@lexfrei in cozystack/website#479).
-
[website] Document the checkbox-then-edit-CR customization pattern for tenants: Describes the workflow for customizing tenant settings via the CR after initial checkbox-based creation (@lexfrei in cozystack/website#485).
-
[website] Add custom Keycloak themes documentation: Covers the theme image contract, configuration, imagePullSecrets, and theme activation in the Keycloak admin console (@lexfrei in cozystack/website#463).
-
[website] Add bonding (LACP) configuration how-to guide: Covers network bonding configuration for Cozystack installations (@sircthulhu in cozystack/website#459).
-
[website] Improve registry mirrors for tenant Kubernetes in air-gapped guide: Improves documentation for configuring registry mirrors in air-gapped environments (@sircthulhu in cozystack/website#461).
-
[website] Rewrite guide for ApplicationDefinition API (external-apps): Comprehensive rewrite of the external apps guide using the ApplicationDefinition API with Minecraft server examples (@kitsunoff in cozystack/website#488).
-
[website] Add documentation for Go types usage: Guide for using generated Go types for Cozystack managed applications as a Go module (@myasnikovdaniil in cozystack/website#465).
-
[website] Update backup/restore documentation for VMI/VMDisk: Updates backup documentation with VM instance and VM disk restore improvements (@androndo in cozystack/website#466).
-
[website] Refactor docs versions to major.minor variants: Moves docs to major.minor versioning for the v1.x series (@myasnikovdaniil in cozystack/website#477).
-
[website] Trunk-based versioning with permanent next/ directory: Replaces the old "pre-create vX.Y/ draft directory" scheme with a permanent content/en/docs/next/ trunk; released version directories are promoted explicitly by hack/release_next.sh on new minor/major releases, and routing between next/ and vX.Y/ is Makefile-driven (@myasnikovdaniil in cozystack/website#495).
-
[website] Add updated OpenAPI spec: Updates the OpenAPI specification for managed applications reference (@myasnikovdaniil in cozystack/website#469).
-
[website] Add OpenAPI spec download to GitHub Pages build: Fixes the GitHub Pages build to include the OpenAPI spec download (@myasnikovdaniil in cozystack/website#494).
-
[website] Add OSS Health pages and OpenSSF badge: Adds OSS Health section with OpenSSF Scorecard and Best Practices badges to the website (@tym83 in cozystack/website#470).
-
[website] Add Telemetry page under OSS Health section: Adds the Telemetry page with initial data seeding to the OSS Health docs (@tym83 in cozystack/website#471, cozystack/website#504).
-
[website] Blog: OSS Health section launch announcement: Publishes the announcement blog post for the OSS Health section (@tym83 in cozystack/website#474).
-
[website] Fix OpenSSF canonical status URL: Changes the OpenSSF canonical status URL from pt-BR to en (@tym83 in cozystack/website#475).
-
[website] Add CozySummit Virtual 2026 program announcement: Publishes the CozySummit Virtual 2026 program announcement blog post (@tym83 in cozystack/website#472).
-
[website] Add missing release announcements for v0.1–v0.41: Backfills missing release announcement blog posts for historical Cozystack versions (@tym83 in cozystack/website#468).
-
[website] Blog: managed PostgreSQL with synchronous replication: Adds a post covering the managed PostgreSQL synchronous-replication feature (@tym83 in cozystack/website#497).
-
[website] Blog taxonomies and client-side filter UI: Registers article-type and topic taxonomies and adds a client-side filter on the blog list page (@tym83 in cozystack/website#499).
-
[website] Add images frontmatter for social preview on existing posts: Adds images frontmatter for social preview on existing blog posts (@tym83 in cozystack/website#498).
-
[website] Fix broken links and stale anchors across v1 docs: Fixes 14 broken links and stale talm anchors (@lexfrei in cozystack/website#486).
-
[website] Prefix bundle package names with cozystack. in v1 examples: Corrects package naming in documentation examples (@lexfrei in cozystack/website#482).
-
[website] Finish isolated-field removal and document opt-in policy labels: Removes the obsolete isolated field from tenant documentation and documents the new opt-in policy labels approach (@lexfrei in cozystack/website#481).
-
[website] Add --take-ownership flag and describe networking. fields*: Documents the --take-ownership flag and networking.* fields in the installation guide (@lexfrei in cozystack/website#480).
-
[website] Fix KubeOVN MASTER_NODES example path and key in troubleshooting: Corrects the MASTER_NODES example path and key (@lexfrei in cozystack/website#483).
-
[website] Add CLAUDE.md for AI agent guidance: Adds a CLAUDE.md file describing the trunk-based docs architecture for AI agent guidance (@myasnikovdaniil in cozystack/website#489).
-
[website] Update /docs/v1/ redirect to latest v1.2: Updates the /docs/v1/ redirect target to point to the latest v1.2 docs on GitHub Pages (@myasnikovdaniil in cozystack/website#492).
-
[website] Remove nbykov from CODEOWNERS and CLAUDE.md: Cleans up CODEOWNERS and CLAUDE.md entries (@myasnikovdaniil in cozystack/website#491).
-
[website] Add Ahrefs Analytics tracker: Adds the Ahrefs Analytics tracker to the website (@tym83 in cozystack/website#503).
-
[website] Add breathing room between navbar and hero on OSS Health: Minor styling fix for the OSS Health section (@tym83 in cozystack/website#500).
-
[website] Fix og social badge image and title: Updates the social badge image and title (@tym83 in cozystack/website#487).
-
[website] Update managed apps reference for v1.2.1: Automated managed-apps reference update (@cozystack-bot in cozystack/website#464).
-
[external-apps-example] Replace MongoDB example with Minecraft apps: Refactors the external apps example to use the ApplicationDefinition API with Minecraft server applications (@lexfrei in cozystack/external-apps-example#2).
-
docs: update README introductory description: Refines the platform positioning and improves clarity on core capabilities in the main README (@tym83 in #2409).
Governance
Contributors
We'd like to thank all contributors who made this release possible:
New Contributors
We're excited to welcome our first-time contributors:
Full Changelog: v1.2.0...v1.3.0
