Installation Instructions

Prerequisites

1. Setup Kubernetes or OpenShift cluster

Supported version of Kubernetes: 1.21 and later.

We recommend AWS (EKS) or Google Cloud (GKE), but you can install it on a standalone cluster as well.

Define your cluster size considering the following minimum requirements and your business needs:

  • Minimal requirements for the Catalyst Package Manager for 1 instance with:

    • 2 core CPU

    • 4GB RAM

    • 10GB disk space

  • Other prerequisites: Canton Participant node, Canton Domain (optional). Minimal requirements for one node:

Node

CPUe

Memory, Gi

Storage, Gi

Domain

1

1

1

Participant

1

1

1

Application

1

1

1

Deciding on the size of the cluster, please consider the expected load of the nodes and increase these values accordingly.

2. Install Helm to your workstation

Installation manuals: helm.sh/docs/intro/install/

No customization is needed.

Supported version of Helm: 3.X.

3. Install Traefik ingress

The ingress-controller is needed for traffic routing to expose nodes (domains & applications). The Catalyst Package Manager creates a CRD resource (IngressRoute in case of using Traefik), that is automatically started and deleted along with each application (and on demand for domains).

No customization is needed, the default port ( :443 ) for HTTPS traffic will be used.

We recommend installing Traefik to a separate namespace from the application (creation of a namespace for the Catalyst Package Manager is described in step 6).

NOTE: Supported version of Traefik: 2.3.

4. Install cert-manager to create TLS certificate

TLS certificate is needed for secured communication between a User and the Сatalyst Package Manager components.

We recommend using the last release of the official helm chart.

You can skip this step and specify your TLS certificate and key as a Kubernetes secret in Helm chart values instead later (Helm chart values are described in the Setup section). You can find the manual on how to create a Kubernetes secret here:

5. Create an A-record in a zone in your domain’s DNS management panel and assign it to the load balancer created upon Traefik or OpenShift installation

Canton Package Manager needs a wildcard record *.<domain>' to expose nodes. All created nodes (domains, participants, applications) will have a <NodeName>.<domainName> address.

For example, in case you are using AWS, follow these steps:

  1. Go to the Route53 service.

  2. Create a new domain or choose the existing domain.

  3. Create an A record.

  4. Switch “alias” to ON.

  5. In the “Route traffic to” field select “Alias to application and classic load balancer.”

  6. Select your region (where the cluster is installed).

  7. Select an ELB balancer from the drop-down list.*

Choose the ELB balancer, which was automatically configured upon the Traefik chart installation as described in step 3 (or upon OpenShift installation in case of using OpenShift).

You can check the ELB by the following command:

kubectl get svc -n `${ingress-namespace`}
  • where

    • ${ingress-namespace} is the name of the namespace, where the ingress was installed.

    • ELB is displayed in the EXTERNAL-IP field.

6. Create a namespace for the Catalyst Package Manager application

kubectl create ns `${ns_name`}

where ${ns_name} — name of namespace (can be any).

6.1 Get the credentials to the Helm repository in the JFrog artifactory provided by the IntellectEU admin team

In case you have any blocker please reach out to catalyst-support@intellecteu.com

6.2 Add the repo to Helm with the username and password provided

helm repo add catbp-canton-package-manager <https://intellecteu.jfrog.io/artifactory/api/helm/catbp-canton-package-manager> --username ${ARTIFACTORY_USERNAME} --password ${ARTIFACTORY_PASSWORD}

As a result: "helm-local" has been added to your repositories

7. Create an ImagePullSecret to access the Catalyst Package Manager deployable images

For example, create this Secret, naming it intellecteu-jfrog-access :

kubectl create secret intellecteu-jfrog-access regcred --docker-server=intellecteu-emtech-cpm-docker.jfrog.io --docker-username= ${your-name} --docker-password= ${your-password} --docker-email=`${your-email} -n ${ns_name}

where: * ${your-name} — your Docker username.

  • ${your-password} — your Docker password.

  • ${your-email} — your Docker email.

  • ${ns_name} — the namespace created for the Catalyst Package Manager on the previous step.

In case you want to use a readiness check and use a private repository for the image, you should create a “secret” file with your credentials in Kubernetes for further specifying it in the Helm chart upon Catalyst Package Manager installation.

Please refer to the official Kubernetes documentation: kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/

Helm chart configuration instructions you will find here.

Install CPM Daml Contract Templates (Dars)

Once logged into jFrog Artifactory download at

Install cpm-0.0.3.dar to your Canton Participant/Validator

Install CPM Helm Chart

Use the following command:

helm install ${cpm_release_name} catbp/canton-package-manager --values values.yaml -n ${ns_name}

where: * ${cpm_release_name} — name of the Catalyst Package Manager release. You can choose any name/alias. It is used to address for updating, deleting the Helm chart. * catbp/canton-package-manager — chart name, where “catbp” is a repository name, “canton-package-manager” is the chart name.

  • values.yaml — a values file.

  • ${ns_name} — name of the namespace you’ve created before

You can check the status of the installation by using these commands:

  • helm ls — check the "status" field of the installed chart.

Status “deployed” should be shown.
  • kubectl get pods — get the status of applications separately.

All pods statuses must be “running.”

kubectl describe pod $pod_name — get detailed information about pods.

Setup

Configure helm chart values

Full list of the helm chart values

# -- address where application will be hosted.
domainName: "cpm.staging.catalyst.intellecteu.io"

nameOverride: "canton-package-manager"
fullnameOverride: "canton-package-manager"

mainService:
  nameOverride: cpm-main-service-2
  enabled: true
  env:
    LEDGER_DOMAIN_ID: ""
    LEDGER_APP_ID: ""
    LEDGER_HOST: ""
    LEDGER_PORT: ""
    PORT: ""
  image:
    repository: intellecteu-emtech-cpm-docker.jfrog.io/cpm-main-service
    tag: 0.0.9-SNAPSHOT
    pullPolicy: IfNotPresent
  imagePullSecrets:
    - cpm-jfrog-access
  replicas: 1
  service:
    type: ClusterIP
    port: 80
    portName: http
  containerPort: 80
  extraEnv: {}
  labels: {}
  podAnnotations: {}
  automountServiceAccountToken: true
  podSecurityContext: {}
    # runAsNonRoot: true
    # runAsUser: 1000
    # runAsGroup: 1000
    # fsGroup: 1000
  securityContext: {}
  updateStrategy: {}
  resources: {}
  nodeSelector: {}
  tolerations: []
  affinity: {}
  probes:
    enabled: false
    livenessProbe:
      initialDelaySeconds: 30
      periodSeconds: 10
      timeoutSeconds: 5
      successThreshold: 1
      failureThreshold: 10
      httpGet:
        path: /accesses
        port: 8080
    readinessProbe:
      initialDelaySeconds: 30
      periodSeconds: 10
      timeoutSeconds: 5
      successThreshold: 1
      failureThreshold: 10
      httpGet:
        path: /accesses
        port: 8080
  licenseKey:
    key: ""
    secret:
      enabled: false
      name: ""
      key: ""
  keycloakClient:
    secret: ""
    externalSecret:
      enabled: false
      remoteSecretRef: ""
      secretStoreRef:
        name: ""
        kind: "SecretStore"

# -- optional Listing Service.
listingService:
  nameOverride: cpm-listing-service-2
  enabled: false
  env:
    TOKEN_URL: ""
    CLIENT_SECRET: ""
    LEDGER_HOST: ""
    PORT: ""
    LEDGER_PORT: ""
    LEDGER_DOMAIN_ID: ""
    KEYCLOAK_REALM: ""
    KEYCLOAK_URL: ""
    KEYCLOAK_CLIENT_ID: ""
    CANTON_LEDGER_ID: ""
  image:
    repository: intellecteu-emtech-cpm-docker.jfrog.io/cpm-listing-service
    tag: 0.0.7-SNAPSHOT
    pullPolicy: IfNotPresent
  imagePullSecrets:
    - cpm-jfrog-access
  replicas: 1
  service:
    type: ClusterIP
    port: 80
    portName: http
  containerPort: 80
  extraEnv: {}
  labels: {}
  podAnnotations: {}
  automountServiceAccountToken: true
  podSecurityContext: {}
    # runAsNonRoot: true
    # runAsUser: 1000
    # runAsGroup: 1000
    # fsGroup: 1000
  securityContext: {}
  updateStrategy: {}
  resources: {}
  nodeSelector: {}
  tolerations: []
  affinity: {}
  probes:
    enabled: false
    livenessProbe:
      initialDelaySeconds: 30
      periodSeconds: 10
      timeoutSeconds: 5
      successThreshold: 1
      failureThreshold: 10
      httpGet:
        path: /list
        port: 8081
    readinessProbe:
      initialDelaySeconds: 30
      periodSeconds: 10
      timeoutSeconds: 5
      successThreshold: 1
      failureThreshold: 10
      httpGet:
        path: /list
        port: 8081
  licenseKey:
    key: ""
    secret:
      enabled: false
      name: ""
      key: ""
  keycloakClient:
    secret: ""
    externalSecret:
      enabled: false
      remoteSecretRef: ""
      secretStoreRef:
        name: ""
        kind: "SecretStore"

ingressConfig:
  # Enable or disable the creation of Ingress resources
  enabled: true
  enableIngressRouteMainhttp: false
  # Select the ingress provider (supported: traefik, traefikCRD)
  provider:
    name: traefikCRD
    traefik:
      # Ingress class name to use when provider is "traefik"
      ingressClass: "traefik"
    traefikCRD:
      tlsStore:
        # Enable or disable creation of TLSStore
        enabled: false
        # Name of the TLSStore to be used (default by Traefik)
        name: default

  # Ingress class name to be applied to all ingress resources
  className: traefik

  # Annotations for HTTP ingress routes
  annotationsHttp:
    traefik.ingress.kubernetes.io/router.entrypoints: web

  # Annotations for HTTPS ingress routes
  annotationsHttps:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure

  # List of domains and their associated paths and services
  hosts:
    - host: cpm.staging.catalyst.intellecteu.io
      paths:
        - path: /cpm-main-service-2
          pathType: Prefix
          service: cpm-main-service-2
        - path: /cpm-listing-service-2
          pathType: Prefix
          service: cpm-listing-service-2

  # TLS configuration options
  tls:
    # Enable or disable TLS for ingress
    enabled: true
    # Name of the existing secret with TLS certs (ignored if certManager is enabled)
    secretName: canton-package-manager-tls
    certManager:
      # Enable automatic certificate management using Cert-Manager
      enabled: true
      # Email to use for Let's Encrypt registration
      email: services.cat-bp@intellecteu.com
      # ACME server URL (production or staging)
      server: https://acme-v02.api.letsencrypt.org/directory

  # Middleware configuration to strip path prefixes before routing
  stripApplicationPrefix:
    enabled: true
    type: regex
    # List of regex patterns to remove from the request path
    regex:
      - "^/[^/]+/api/?"
    prefixes:
      - "^/cpm-main-service-2"
      - "^/cpm-listing-service-2"


monitoring:
  # -- Enable integration with a prometheus-operator. The module fetches metrics from the canton nodes in the system.
  # Prometheus operator and grafana need to be installed beforehand
  enabled: false
  url:
  # -- Configuration for ServiceMonitor resource
  serviceMonitor:
    # -- How often to pull metrics from resources
    interval: 30s
  # -- Configuration for prometheusRules resource
  prometheusRules:
    enabled: false
    # Additional prometheusRules labels
    labels: {}
  grafana:
    enabled: false
    # -- grafana default admin username and email. Grafana is authenticated through default API authentication automatically.
    # -- grafana normal URL
    url: ""
    user: admin
    email: admin@domain.com
    # -- grafana default path to dashboard
    clusterDashboard: ""
    # -- grafana service and port for ingress
    service:
      name: grafana
      namespace: monitoring
      port: 80

Install CPM CLI client

Download CPM CLI JAR executable at

Create a configuration file containing a JSON object with the following keys:

  • authUrl: Device Authorization Endpoint of your OAuth 2.0 provider.

  • tokenUrl: Token Endpoint of your OAuth 2.0 provider.

  • authClientId: The client id to use when obtainaing an access token.

  • listingUrl: The URL of the listing service to use.

  • mainUrl: The URL of your main service.

Example:

{
    "authUrl": "https://YOUR_KEYCLOAK/auth/realms/YOUR_REALM/protocol/openid-connect/auth/device",
    "tokenUrl": "https://YOUR_KEYCLOAK/auth/realms/YOUR_REALM/protocol/openid-connect/token",
    "authClientId": "cpm-cli",
    "listingUrl": "https://participant-cpm-validator.canton.prod.catalyst.intellecteu.io/cpm-listing-service/api",
    "mainUrl": "https://your-main-service"
}

You can then run the cpm cli as java -jar cli-<VERSION>.jar --config-file <CONFIG_FILE>

or to make things a bit nicer use the following snippets to create a cpm function in your shell to make usage easier:

Unix (bash/zsh)

function cpm { java -jar target/cli-<VERSION>.jar --config-file <CONFIG_FILE> $@ }

Windows (powershell)

function cpm { java -jar target/cli-<VERSION>.jar --config-file <CONFIG_FILE> $@ }