Prerequisites
Before deploying CIVITAS/CORE V2, ensure that your Kubernetes cluster is configured and all required tools are installed.
Cluster Requirements
A Kubernetes cluster is required to deploy CIVITAS/CORE V2. The Deployment tries to focus on the platform itself without providing additional cluster-wide tooling.
Your target Kubernetes cluster must meet the following requirements:
- Kubernetes nodes: x86_64 architecture (ARM64 support is currently not supported, but planned for the future)
- Kubernetes version: 1.32 or higher
- Minimum resources: 4 CPUs, 16 GB RAM (for development deployment)
- Recommended resources: 8+ CPUs, 32+ GB RAM
- Cluster-level components (must be installed before deploying CIVITAS/CORE):
| Component | Purpose | Required |
|---|---|---|
| Ingress Controller (e.g. nginx, traefik) | Routes external traffic to services | Yes |
cert-manager (with at least one cluster issuer (e.g. letsencrypt-prod) | Automated TLS certificate provisioning | Yes |
| Storage Class (with rwo support) | Provider for persistent storage volumes | Yes |
| Kyverno | Admission/background controller for the runtime ClusterPolicy objects (enabled by default) | Strongly recommended |
| Linkerd | Service mesh with mTLS; enabled by default and enforcing mandatory mTLS (see below) | Strongly recommended |
| Metrics server | Data provider for autoscaling (optional but recommended) | No |
In addition, the following requirements must be met:
- Full Cluster Admin Rights: required to create cluster-scoped resources (e.g. CloudNativePG operator + CRDs)
- Domain with DNS records: pointing to ingress endpoint for all configured domains
Linkerd Service Mesh
While Linkerd is not strictly required, it is highly recommended to use it for secure service-to-service communication (mTLS) and observability features. If you choose to use Linkerd, ensure that it is installed and properly configured in your cluster before deploying CIVITAS/CORE V2. Be sure to set proxy.nativeSidecar=true in the deployment configuration to enable native sidecar injection for better reliability, especially with Init Jobs.
Any other service mesh can be used as well, but may require additional configuration and testing to ensure compatibility with CIVITAS/CORE V2. We chose Linkerd for the reference deployment due to its simplicity, high performance and low resource usage.
Mandatory mTLS is the default. When the service mesh is enabled (the default), the prepare step annotates every instance namespace with config.linkerd.io/default-inbound-policy: cluster-authenticated (configurable via global.serviceMesh.defaultInboundPolicy). Only authenticated, meshed in-cluster clients may then connect, so the ingress controller must itself be meshed. If your ingress controller cannot be meshed (e.g. in a shared cluster), set global.serviceMesh.allowUnauthenticatedIngress: true. See Security Hardening → Service Mesh Authorization.
Kyverno (Runtime Policies)
By default the platform deploys a set of in-cluster Kyverno ClusterPolicy objects (the runtime-policies component). This requires Kyverno to be already running in the cluster — the platform ships only the policies, not Kyverno itself. If you do not want the runtime policies, disable them with global.runtimePolicies.enabled: false — Kyverno is then not required. See Security Hardening → Runtime Kyverno Policies.
Domain and DNS Configuration
You will need a domain name with DNS records pointing to the ingress endpoint of your Kubernetes cluster. Each component that exposes an ingress derives its host from its own subdomain setting (see the component's default-environment.yaml.gotmpl). With the default components enabled, the following subdomains are expected to be configured:
idm.<your-domain>: Keycloak authentication serverportal.<your-domain>: user & data management portalapi.<your-domain>: Payload API
Secrets
Some secrets are expected to be already present in the cluster before deploying CIVITAS/CORE V2.
Because everything is in one namespace, you must create the namespace first before creating the secrets.
kubectl create namespace YOUR_NAMESPACE
A simpler solution to (a) see what secrets are needed and (b) create them will be added later.
Required Secrets:
- Keycloak SMTP Configuration:
- Secret Name:
keycloak-smtp - Keys:
host: SMTP server hostport: SMTP server portfrom: Email address for sending emailsuser: SMTP usernamepassword: SMTP password
- Secret Name:
It is possible to use an invalid SMTP server like the one below, with the following implications:
- The initial user will get no email link to set its password, but will have to do it via the keycloak admin console.
- Users will not be able to reset their password via email.
- For all newly created users, the same manual steps will be required to set their password.
kubectl create secret generic keycloak-smtp \
--from-literal=host='smtp.example.com' \
--from-literal=port='587' \
--from-literal=from='noreply@example.com' \
--from-literal=user='noreply@example.com' \
--from-literal=password='YOUR_SMTP_PASSWORD' \
-n YOUR_NAMESPACE
Local Requirements
Required tools
Install the following tools on the machine from which you will run the deployment:
| Tool | Minimum Version | Purpose |
|---|---|---|
| kubectl | v1.32+ | Kubernetes CLI for cluster interaction |
| Helm | 3.18+, Helm 4 supported as well | Kubernetes package manager |
| Helm Diff Plugin | - | Helm Plugin required by helmfile |
| helmfile | 1.1.9+ | Declarative Helm chart orchestration |
| Git | 2.0+ | Clone the deployment repository |
Verify your installations:
kubectl version --client
helm version
helmfile version
Clone Deployment Repository
Clone this repository to your local machine to get started with the deployment process. It is not necessary to make any changes or fork this repository unless you want to contribute to the core deployment configurations. The actual deployment configurations should be done in a separate deployment directory as described in the Configuration Guide.
git clone https://gitlab.com/civitas-connect/civitas-core/civitas-core-v2/civitas-core-deployment.git
cd civitas-core-deployment