Launching the Platform/Self hosted

Platform Installation

Overview

This guide walks you through installing the SettleMint Platform using Helm, providing a command-line based installation method with full control over the deployment process.

Prerequisites

Before starting the installation, ensure you have:

  • Completed all prerequisite services setup
  • Collected all required information from the prerequisite guides
  • Met all infrastructure requirements
  • Helm 3.x installed
  • kubectl access to your cluster
  • Admin permissions

Installation Steps

1. Sign in to the SettleMint Helm Registry

helm registry login harbor.settlemint.com --username <username> --password <password>

Replace <username> and <password> with your provided credentials.

2. Review Configuration Options

View all available configuration options:

helm show values oci://registry.settlemint.com/settlemint-platform/settlemint --version 7.0.0

3. Install the Platform

Create a values file (values.yaml) with your configuration:

ingress:
  enabled: true
  className: "nginx"
  host: '<your-domain>'
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/proxy-ssl-server-name: "on"
    nginx.ingress.kubernetes.io/proxy-body-size: "500m"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    cert-manager.io/cluster-issuer: "letsencrypt"  # If using cert-manager
  tls:
    - secretName: 'platform-tls'
      hosts:
        - '<your-domain>'
        - '*.<your-domain>'
 
redis:
  host: '<redis-host>'
  port: '<redis-port>'
  password: '<redis-password>'
  tls: true
 
postgresql:
  host: '<postgresql-host>'
  port: '<postgresql-port>'
  user: '<postgresql-user>'
  password: '<postgresql-password>'
  database: '<database-name>'
  sslMode: require
 
auth:
  jwtSigningKey: '<your-jwt-signing-key>'
  providers:
    google:
      enabled: true
      clientID: '<google-client-id>'
      clientSecret: '<google-client-secret>'
    microsoftEntraId:
      enabled: true
      clientID: '<microsoft-client-id>'
      clientSecret: '<microsoft-client-secret>'
      tenantId: '<microsoft-tenant-id>'
 
vault:
  address: '<vault-address>'
  roleId: '<vault-role-id>'
  secretId: '<vault-secret-id>'
  namespace: 'vault'
 
features:
  observability:
    metrics:
      enabled: true
      apiUrl: '<victoria-metrics-url>'
    logs:
      enabled: true
      apiUrl: '<loki-url>'
  deploymentEngine:
    platform:
      domain:
        hostname: '<your-domain>'
    clusterManager:
      domain:
        hostname: '<your-domain>'
    state:
      connectionUrl: 's3://<bucket-name>?region=<region>'
      secretsProvider: 'passphrase'
      credentials:
        encryptionKey: '<your-encryption-key>'
        aws:
          accessKeyId: '<aws-access-key>'
          secretAccessKey: '<aws-secret-key>'
          region: '<aws-region>'
        # azure:
        #   # -- Azure storage account name
        #   storageAccount: '<azure-storage-account>'
        #   # -- Azure storage account key
        #   storageKey: '<azure-storage-key>'
    targets:
      - id: '<cluster-id>'
        name: '<cluster-name>'
        icon: '<cluster-icon>'
        clusters:
          - id: '<cluster-instance-id>'
            name: '<cluster-instance-name>'
            icon: '<cluster-instance-icon>'
            location:
              lat: '<latitude>'
              lon: '<longitude>'
            connection:
              sameCluster:
                enabled: true
            namespace:
              single:
                name: '<namespace>'
            domains:
              service:
                tls: true
                hostname: '<your-domain>'
            storage:
              storageClass: '<storage-class>'
            ingress:
              ingressClass: '<ingress-class>'
            capabilities:
              mixedLoadBalancers: false
 
app:
  replicaCount: '<replicas>'
api:
  replicaCount: '<replicas>'
  existingSecret: '<platform-secret>'
job:
  resources:
    requests:
      cpu: '<cpu-request>'
      memory: '<memory-request>'
  autoscaling:
    enabled: true
deployWorker:
  resources:
    requests:
      cpu: '<cpu-request>'
      memory: '<memory-request>'
  autoscaling:
    enabled: true
clusterManager:
  replicaCount: '<replicas>'
docs:
  replicaCount: '<replicas>'
 
imagePullCredentials:
  registries:
    harbor:
      enabled: true
      registry: "harbor.settlemint.com"
      username: '<registry-username>'
      password: '<registry-password>'
      email: '<registry-email>'
 
support:
  kubernetes-replicator:
    enabled: true
 
features:
  billing:
    enabled: false
    alerting:
      slack:
        enabled: false
        webhookUrl: ''
    stripe:
      apiSecret: ''
      webhookSecret: ''
      webhookUrl: ''
      apiLiveMode: false
      taxRateId: ''
      publishableKey: ''
    autoDelete:
      enabled: false
    emailUsageExcel:
      enabled: true
 
  privateKeys:
    hsm:
      awsKms:
        enabled: false
    txsigner:
      image:
        registry: ghcr.io
        repository: settlemint/btp-signer
        tag: '7.6.10'
 
  networks:
    besu:
      image:
        registry: docker.io
        repository: hyperledger/besu
        tag: '24.12.2'
    quorum:
      image:
        registry: docker.io
        repository: quorumengineering/quorum
        tag: '24.4.1'
    geth:
      image:
        registry: docker.io
        repository: ethereum/client-go
        tag: 'alltools-v1.13.4'
    fabric:
      ca:
        image:
          registry: docker.io
          repository: hyperledger/fabric-ca
          tag: '1.5.13'
      orderer:
        image:
          registry: docker.io
          repository: hyperledger/fabric-orderer
          tag: '2.5.10'
      tools:
        image:
          registry: docker.io
          repository: hyperledger/fabric-tools
          tag: '2.5.10'
      peer:
        image:
          registry: docker.io
          repository: hyperledger/fabric-peer
          tag: '2.5.10'
      couchdb:
        image:
          registry: docker.io
          repository: apache/couchdb
          tag: '3.4.2'
      dind:
        image:
          registry: docker.io
          repository: library/docker
          tag: '24.0.7-alpine3.18'
    mainnets:
      enabled: true
      ethereumMetricsExporter:
        image:
          registry: docker.io
          repository: ethpandaops/ethereum-metrics-exporter
          tag: '0.26.0'
 
  smartContractSets:
    etherscan:
      apiKeys:
        etherscan: ""
        polyscan: ""
        zkevmpolyscan: ""
        bscscan: ""
        arbiscan: ""
        optimistic: ""
    ide:
      image:
        registry: ghcr.io
        repository: settlemint/btp-ide
        tag: 'v7.6.5'
    sets:
      - id: starterkit-asset-tokenization
        name: Asset Tokenization
        image:
          registry: ghcr.io
          repository: settlemint/starterkit-asset-tokenization
          tag: '0.0.11'
      # ... (other sets can be added as needed)
 
  customDomains:
    enabled: false
    outerIngressClass: "nginx"
    email: ""
 
  crons:
    cleanup: "0 */10 * * * *"

Replace all placeholder values with your actual configuration - The license section should be configured with your provided license file - Image tags should be verified for the latest stable versions - Remove any unused features to keep the configuration clean

Click to see a complete example values file
ingress:
  enabled: true
  className: "nginx"
  host: "example.company.com"
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/proxy-ssl-server-name: "on"
    nginx.ingress.kubernetes.io/proxy-body-size: "500m"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    cert-manager.io/cluster-issuer: "letsencrypt"
  tls:
    - secretName: "example-tls"
      hosts:
        - "example.company.com"
        - "*.example.company.com"
 
redis:
  host: "redis.example.local"
  port: "6379"
  password: "abc123password"
  tls: true
 
postgresql:
  host: "postgresql.example.local"
  port: "5432"
  user: "db_user"
  password: "xyz789password"
  database: "platform_db"
  sslMode: require
 
auth:
  jwtSigningKey: "abc123jwt456xyz789signing000key111example"
  providers:
    google:
      enabled: true
      clientID: "example-123456789.apps.googleusercontent.com"
      clientSecret: "abcdef-example-google-secret"
 
vault:
  address: "http://vault.example.local:8200"
  roleId: "abc123-role-id"
  secretId: "xyz789-secret-id"
  namespace: "vault"
 
features:
  observability:
    metrics:
      enabled: true
      apiUrl: "http://metrics.example.local/api/v1"
    logs:
      enabled: true
      apiUrl: "http://logs.example.local/api/v1"
  deploymentEngine:
    platform:
      domain:
        hostname: "example.company.com"
    state:
      connectionUrl: "s3-compatible-endpoint-url"
      secretsProvider: "passphrase"
      credentials:
        encryptionKey: "abc123encryption456key789example000key"
        aws:
          accessKeyId: "EXAMPLEKEYID123456"
          secretAccessKey: "abc123example456secret789key000aws"
          region: "us-east-1"
        azure:
          storageAccount: "example-storage-account"
          storageKey: "abc123example456key789key000azure"
        google:
          project: "example-project-id"
          credentials: |
            {
              "type": "service_account",
              "project_id": "your-project",
              "private_key_id": "key-id",
              "private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
              "client_email": "[email protected]",
              "client_id": "client-id",
              "auth_uri": "https://accounts.google.com/o/oauth2/auth",
              "token_uri": "https://oauth2.googleapis.com/token",
              "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
              "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/[email protected]"
            }
    targets:
      - id: "example"
        name: "Example Cluster"
        icon: "kubernetes"
        clusters:
          - id: "main"
            name: "Main"
            icon: "global"
            location:
              lat: 0.0000
              lon: 0.0000
            connection:
              sameCluster:
                enabled: true
            namespace:
              single:
                name: "example"
            domains:
              service:
                tls: true
                hostname: "example.company.com"
            storage:
              storageClass: "standard"
            ingress:
              ingressClass: "nginx"
 
app:
  replicaCount: "2"
api:
  replicaCount: "2"
  existingSecret: "example-secret"
job:
  resources:
    requests:
      cpu: "100m"
      memory: "512Mi"
deployWorker:
  resources:
    requests:
      cpu: "100m"
      memory: "512Mi"
clusterManager:
  replicaCount: "2"
 
imagePullCredentials:
  registries:
    harbor:
      enabled: true
      registry: "harbor.settlemint.com"
      username: "example_user"
      password: "abc123registry456password"
      email: "[email protected]"
 
support:
  kubernetes-replicator:
    enabled: true

Install the platform:

helm upgrade --install settlemint oci://registry.settlemint.com/settlemint-platform/settlemint \
  --namespace settlemint \
  --version 7.0.0 \
  --create-namespace \
  --values values.yaml

4. Verify Installation

Check the deployment status:

kubectl get pods -n settlemint

Verify all pods are running and ready.

5. Access the Platform

Once all pods are running, access the platform at https://<your-domain>.

6. Target Clusters Configuration

The platform supports deploying blockchain nodes and applications to multiple target clusters across different cloud providers and regions. This section explains how to configure target clusters in your values file.

Target Structure

The targets configuration uses a simple 2-level hierarchy:

  • Target (top level grouping)
  • Clusters (individual Kubernetes clusters)

Basic Configuration Example

features:
  deploymentEngine:
    targets:
      - id: GROUP1
        name: First Group
        icon: cloud
        clusters:
          - id: CLUSTER1
            name: Primary Cluster
            icon: kubernetes
            location:
              lat: 50.8505
              lon: 4.3488
            namespace:
              multiple:
                enabled: true
                prefix: "sm"
            connection:
              kubeconfig:
                enabled: true
            domains:
              service:
                tls: true
                hostname: "cluster1.example.com"
            storage:
              storageClass: "standard"
            ingress:
              ingressClass: "nginx"
            capabilities:
              mixedLoadBalancers: false
              nodePorts:
                enabled: true
                range:
                  min: 30000
                  max: 32767
      - id: GROUP2
        name: Second Group
        icon: cloud
        clusters:
          - id: CLUSTER2
            name: Secondary Cluster
            icon: kubernetes
            location:
              lat: 1.3521
              lon: 103.8198
            namespace:
              multiple:
                enabled: true
                prefix: "prod"
            connection:
              kubeconfig:
                enabled: true
            domains:
              service:
                tls: true
                hostname: "cluster2.example.com"
            storage:
              storageClass: "standard"
            ingress:
              ingressClass: "nginx"
            capabilities:
              mixedLoadBalancers: true
              nodePorts:
                enabled: true
                range:
                  min: 30000
                  max: 32767

Configuration Options

Target Level
  • id: Unique identifier for the target group
  • name: Display name
  • icon: Icon identifier for the UI
Cluster Level
  • id: Unique identifier for the cluster
  • name: Display name for the region/location
  • icon: Icon identifier for the UI
  • disabled: (Optional) Set to true to disable this cluster
  • location: Geographic coordinates for visualization
    • lat: Latitude
    • lon: Longitude
Namespace Configuration
namespace:
  single:
    enabled: false # Use for single namespace deployments
    name: deployments
    runAsUser: 2024
    fsGroup: 2024
  multiple:
    enabled: true # Use for multiple namespace deployments
    prefix: "sm" # Prefix for created namespaces
Connection Settings
connection:
  sameCluster:
    enabled: false
  kubeconfig:
    enabled: true
Domain Configuration
domains:
  service:
    tls: true # Enable TLS for the domain
    hostname: "cluster.example.com" # Domain for accessing services

The domain configuration determines how services in the cluster will be accessed. Each cluster needs a unique domain that resolves to its ingress controller.

Storage Configuration
storage:
  storageClass: "standard" # Default storage class for the cluster

Storage class recommendations per cloud provider:

  • GKE: Use "standard" for general purpose or "premium-rwo" for better performance
  • EKS: Use "gp3" for general purpose or "io1" for high-performance workloads
  • AKS: Use "managed-premium" for production or "default" for development
Ingress Configuration
ingress:
  ingressClass: "nginx" # Ingress controller class name

The ingress class should match your installed ingress controller. Common options:

  • "nginx" for NGINX Ingress Controller
  • "azure/application-gateway" for Azure Application Gateway
  • "alb" for AWS Application Load Balancer
Capabilities Configuration
capabilities:
  mixedLoadBalancers: false # Support for mixed LoadBalancer services
  nodePorts:
    enabled: true # Enable NodePort service type
    range: # Port range for NodePort services
      min: 30000
      max: 32767

Capabilities determine what features are available in the cluster:

  • mixedLoadBalancers: Enable if your cluster supports both internal and external load balancers
  • nodePorts: Configure if you need to expose services using NodePort type
    • The port range should be within Kubernetes defaults (30000-32767)
    • Ensure the range doesn't conflict with other services

Important Considerations

  1. Domain Names

    • Each cluster must have a unique domain name
    • Domains should be properly configured in your DNS provider
    • TLS certificates will be automatically managed if cert-manager is configured
  2. Storage Classes

    • Verify the storage class exists in your cluster before using it
    • Consider performance requirements when selecting storage classes
    • Some features may require specific storage capabilities (e.g., RWX support)
  3. Network Capabilities

    • mixedLoadBalancers should match your cloud provider's capabilities
    • NodePort ranges should not conflict with other services
    • Ensure network policies allow required communication

When setting up a new cluster, start with the basic configuration and gradually enable additional capabilities as needed. This approach helps in identifying potential issues early in the deployment process.

Troubleshooting

If you encounter issues during installation:

  1. Debug the installation:
helm upgrade --install --debug --dry-run settlemint oci://registry.settlemint.com/settlemint-platform/settlemint \
  --namespace settlemint \
  --values values.yaml
  1. Check pod logs:
kubectl logs -n settlemint <pod-name>
  1. Generate a support bundle:
# Install support bundle plugin
curl https://krew.sh/support-bundle | bash
 
# Generate bundle
kubectl support-bundle --load-cluster-specs

Send the generated support bundle to [email protected] for assistance.

Uninstalling

To remove the platform:

helm delete settlemint --namespace settlemint

Note: This will not delete persistent volumes or other resources outside of Helm's control. You may need to clean these up manually.