Skip to main content
Version: V2-Next

Deployment

Deployment Model

CIVITAS/CORE V2 is deployed exclusively on Kubernetes using Helmfile to orchestrate multiple Helm charts. There is no Docker Compose or VM-based deployment model.

Supported Environments

EnvironmentSupport LevelNotes
Kubernetes (x86_64)Fully supportedProduction and development
Kubernetes (ARM64)Not officially supportedPlanned for the future
Docker ComposeNot availableUse the local k3d deployment for development
Virtual MachinesNot availableKubernetes is required

Namespace Strategy

Currently, CIVITAS/CORE V2 deploys all components into a single namespace named after global.instanceSlug (e.g. dev). Multi-namespace deployments are planned but not yet supported.

Deployment Profiles

The global.profile setting controls environment-specific behavior:

Aspectdevelopmentproduction
Resource requests/limitsLowerHigher
ReplicasSingleMultiple (HA, where applicable)

Secrets

If you haven't already, make sure to create the required secrets in your cluster before deploying CIVITAS/CORE V2. You can find the list of required secrets in the prerequisites documentation.

First Deployment

To deploy a certain environment (e.g., testing), navigate to your deployment directory and run:

helmfile -f deployment/helmfile.yaml sync -e testing

This will:

  1. Install CRDs for CloudNativePG and Strimzi operators
  2. Generate secrets for all components
  3. Deploy PostgreSQL, Etcd, and Kafka infrastructure
  4. Deploy application components (Keycloak, Portal, APISIX, etc.)

The component deployment order is defined by the components list in global.yaml and respects inter-component dependencies.

Subsequent Deployments

If CRDs are already installed, it is also possible to run apply, which will only apply changes instead of doing a full sync. This is faster for subsequent deployments after the initial deployment.

helmfile -f deployment/helmfile.yaml apply -e testing

Deploying a Single Component

To deploy or update a specific component without redeploying everything:

helmfile -f deployment/helmfile.yaml apply -e testing --selector component=keycloak

Replace keycloak with the component name. This is useful for iterating on individual components.

Dry-Run / Preview

To see what would be deployed without making changes:

# Render all templates (dry-run)
helmfile -f deployment/helmfile.yaml template -e testing

# Validate templates without deploying
helmfile -f deployment/helmfile.yaml lint -e testing

Tips and Tricks

tip

Some helpful flags:

  • -i or --interactive: Shows a diff of what will be changed and prompts for confirmation before applying changes (only for apply command).
  • --selector component=<component-name>: Deploys only the specified component. Component name must be camelCase.

You can set your kubeconfig with export KUBECONFIG=<path>. It uses always the current context set with kubectl config set-context.

Runnable Example

A minimal production deployment from scratch:

# 1. Clone the deployment repository
git clone https://gitlab.com/civitas-connect/civitas-core/civitas-core-v2/civitas-core-deployment.git
cd civitas-core-deployment

# 2. Create your deployment directory
cp -r defaults/deployment deployment

# 3. Create a production environment
mkdir -p deployment/environments/production

# 4. Configure the environment
cat > deployment/environments/production/global.yaml.gotmpl << 'EOF'
global:
domain: civitas.example.com
instanceSlug: prod
profile: production
initialUserEmail: replace-with-your-email@example.com
ingress:
clusterIssuer: 'letsencrypt-prod'
ingressClass: 'nginx'
EOF

For `initialUserEmail` a platform admin will be created later. This user is your initial user to log into the portal and to create other desired users.

# 5. Register the environment in helmfile.yaml
# (edit deployment/helmfile.yaml to add 'production' to environments and helmfiles sections)

# 6. Create required secrets
kubectl create namespace prod
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 prod

# 7. Deploy
helmfile -f deployment/helmfile.yaml sync -e production