Installation process
What SettleMint does during a self-hosted DALP deployment: four phases from environment verification through blockchain wiring to handoff, with clear owner assignments at each stage.
SettleMint installs DALP self-hosting as a managed deployment. Your team provides the target Kubernetes or OpenShift environment, the infrastructure prerequisites, environment values, and the agreed change window. SettleMint installs the platform charts, wires the blockchain-specific configuration, verifies the deployment, and hands over the endpoint and operating details.
Installation model
The installation has four phases. Each phase has a clear owner so infrastructure teams know what to prepare and what SettleMint validates before handoff.
| Phase | Primary owner | Exit condition |
|---|---|---|
| Pre-installation verification | Joint | Cluster access, managed services, DNS, TLS, storage, and approvals are ready |
| Platform deployment | SettleMint | DALP charts and enabled support services are running in the target environment |
| Post-deployment setup | SettleMint | Contract, network, endpoint, and indexing references are in place |
| Verification and handoff | Joint | Routes, authentication, observability, backups, and access details are verified |
What SettleMint delivers
| Deliverable | Description |
|---|---|
| Helm chart package | Versioned charts for DALP, support, and observability components |
| Image registry credentials | Harbor credentials for harbor.settlemint.com |
| Baseline configuration | Deployment-ready defaults matched to your environment |
| Deployment plan | Verified install sequence and validation checklist |
What clients provide
| Requirement | Description |
|---|---|
| Kubernetes or OpenShift access | kubeconfig with permissions to install charts, CRDs, and namespace resources |
| Prerequisites | All items from the prerequisites checklist |
| Environment values | Domains, TLS material, datastore settings, object storage settings, and service credentials |
| Change window | Time window for deployment, verification, and rollback decisions |
| Post-setup access | Network access for contract deployment, chain indexing, and endpoint validation |
Installation stages
Stage 1: Pre-installation verification
Before installation starts, SettleMint and the client infrastructure team confirm that the target environment matches the prerequisites checklist. Address any gaps before the work begins.
- Validate cluster access, namespaces, and storage classes
- Verify PostgreSQL, Redis, and object storage connectivity
- Confirm DNS and TLS readiness for enabled routes
- Review CRD approvals and security constraints, including SCCs on OpenShift
- Record whether the cluster runs a node-level DNS cache, such as GKE NodeLocal DNSCache
The DNS question belongs in this stage because it changes what a network policy can express. A node-level cache answers pod lookups from a host-network daemon and leaves the packet addressed to the cluster DNS service, so the packet matches no pod and no namespace. The charts therefore ship a port-53 egress rule that names no destination, and the chart tests enforce that shape in every policy that enforces egress. A policy that admits only ingress restricts no outbound traffic and carries no such rule. Do not narrow the rule in an overlay. Adding a pod, namespace, or IP-range destination to it breaks name resolution for every workload on a caching node, and the symptom appears as broad service failure rather than as a DNS error.
Stage 2: Platform deployment
SettleMint installs the Helm charts and brings DALP services online in the target cluster.
- Install operators and supporting charts in the required order
- Deploy DALP services and networking: Ingress on Kubernetes, Routes on OpenShift
- Apply default labels, annotations, and security settings
- Verify the approved application image digests and provenance before workloads start
When this stage completes, all core services are running and reachable inside the cluster.
The deployment sequence applies versioned database migrations before exposing the DAPI role deployments, so the Workflow Engine and Ledger Index start against the schema they own. This ordering is the operating invariant for upgrades and rollback: migration state and indexed checkpoints are reviewed with the release, and verification confirms that reads remain available after the backend becomes ready.
A release can also require an index rebuild, and that is a different obligation from a migration. Migrations are a gate: they complete before the backend serves traffic, and a failure stops the release. An index rebuild is not a gate. It runs behind a healthy, serving deployment, and the read models it rebuilds are incomplete for earlier periods until it drains. On a first installation there is nothing to rebuild, because the deployment starts on the release's own indexing behaviour. On an upgrade, check the release notes for a required rebuild and plan it into the change window rather than discovering it from a report.
When a migration fails and stops the release, the failed migration job is kept
in the namespace instead of being removed with the rest of the release. Its pod
and logs stay readable for 24 hours, so the cause can be read directly from the
cluster or from collected logs without reproducing the upgrade. The next upgrade
reclaims the previous job before it starts, so failed jobs do not accumulate.
Adjust dapp.migrator.ttlSecondsAfterFinished to change the retention window,
or dapp.migrator.hookDeletePolicy where your environment requires the job to
be removed as soon as it fails.
Application images arrive as complete, immutable release units. The cluster does not fetch application packages or assemble services during installation. This allows the same reviewed image digests to be mirrored into restricted registries, promoted between environments, and restored during rollback while configuration and secrets remain environment-owned.
Release images are published as Linux AMD64 and ARM64 manifest lists. The registry resolves the matching variant for each node; mixed-architecture clusters can therefore use the same release reference. The DAPI variant contains a bytecode-enabled Bun executable in a non-root distroless base and starts it directly. Verify that every production node reports one of the supported architectures before rollout; Bun does not provide a Linux PPC64LE executable, so PPC64LE nodes cannot schedule the application workloads.
The DAPI subchart always deploys explicit api, runner, and indexer roles.
Each role binds a health port before it builds its role graph. The /healthz
startup probe allows that bootstrap to complete before liveness restarts are
enabled. /readyz remains the role-readiness check and returns a structured
503 when PostgreSQL or a role dependency is unavailable. Only API pods are
selected by the public Service. During verification, inspect startup, liveness,
and readiness events for each role so a slow bootstrap is not mistaken for an
ingress or route failure.
The readiness check reaches PostgreSQL through a dedicated direct health
session, so application-pool queueing cannot create a false 503. The backend bounds the PostgreSQL leg at eight
seconds and the in-memory host leg at one second, reports an expiry as an
unavailable dependency, and the probe itself allows 10 seconds over a longer
period so the checks cannot overlap it. An unreachable database fails the
check immediately, so the eight-second bound only decides how much pool
waiting turns into a 503; a tighter bound makes readiness flap on transient
database delays across every role at once. Keep the bound itself: an unbounded
check returns nothing at all, which the kubelet cannot tell apart from a dead
process, so one slow but reachable database could drop every API replica from
the Service and stall an update configured to stay at full capacity. When
sizing the deployment, run the chart's connection-budget gate for all three
roles and inspect their direct health-session and pool gauges separately.
Size the Helm wait timeout for the three role rollouts rather than accepting a tool default. API, runner, and indexer pods have separate rollout strategies, and each new pod spends its boot window before readiness. A short wait can abort and roll back a release that was progressing normally.
Chart groups installed during platform deployment
The deployment uses separate chart groups so you can manage platform components, data dependencies, and observability tooling on independent upgrade cycles.
| Chart group | What it installs |
|---|---|
| DALP | Console, three DAPI role Deployments, optional Blockscout, documentation, and optional PostgreSQL metrics exporter |
| Support | Ingress or gateway components, PostgreSQL, Redis, secret reloader, object storage, and backup tooling |
| Observability | Metrics, logs, traces, profiles, native V2 dashboards, alert rules, node metrics, and Kubernetes state metrics |
The DALP chart's log settings are telemetry.logs.enabled, telemetry.logs.exporter, telemetry.logs.level, and the OTLP endpoint. There is no value that selects a console format: the workload always writes to its console and, when the exporter is otlp, always exports the same records to the collector. An installation that points a non-production environment at a shared collector therefore contributes its full log stream to that collector's retention and quota. Set telemetry.logs.exporter to none to keep an environment's logs on the console alone, and raise telemetry.logs.level to reduce volume on both surfaces at once.
Verbose API request and response logging is a separate application setting. It
is disabled by default. Set app.logApiRequests in the chart, or
LOG_API_REQUESTS=true in the workload environment, only for a bounded
diagnostic window because it increases log volume.
The chart groups install into separate namespaces, so the export path from an
application workload to the collector crosses a namespace boundary. Two
settings describe that path, and an installation that moves the Observability
release must change both in the same change.
global.observability.namespace names the namespace that holds the
Observability release. The platform charts build their telemetry egress network
policy from it, and the platform also uses it to reach the query endpoints for
the support bundle.
The OTLP destinations are separate values, and the charts do not derive them from that namespace. Each one ships with the default namespace inside the address, so each one must be changed as well:
| Value | What it carries |
|---|---|
global.dalpApp.config.telemetry.traces.otlp.endpoint | Trace export |
global.dalpApp.config.telemetry.metrics.otlp.endpoint | Metric export |
global.dalpApp.config.telemetry.logs.otlp.endpoint | Log export |
global.dalpApp.config.telemetry.profiling.endpoint | Profile export |
dapp.secretEnv.OTEL_EXPORTER_OTLP_ENDPOINT | The Console's own exporter |
Changing only the namespace value produces the failure this table exists to
prevent: the network policy admits the new namespace while the workloads still
dial the old one, so every signal is denied. Changing only the addresses
produces the same result from the other side, because the policy then denies
the namespace the workloads reach for. In both cases the workloads stay ready
and keep writing records to their console while nothing arrives, because the
shipped configuration does not collect that console output as a second path.
Setting alloy.dalp.logIngest.dropScrapedAppLogs to false restores it, which
brings logs back in a degraded form while metrics and traces stay blocked, so
use that only as a recovery step and read partial telemetry as a symptom rather
than a return to health. Verify after the change that
logs and metrics for the moved release appear under their own deployment
identity.
Verify the log-stream alerts at the same time, and expect them to be quiet. The platform watches each application log stream with a rule that alerts on absence. That rule reports nothing while the stream arrives, and it fires only after the stream stops for the configured period. A rule of that shape must treat no data as healthy, because no data is its normal result. If these rules instead send a continuous data-source notification while logs are arriving, the rule is misconfigured and the notification is not evidence of a collector fault. Do not silence the route to stop that noise. A silenced route also hides the real alert, which uses the same path. Correct the rule instead, then confirm that the alert returns to an inactive state while the stream is present.
Upgrading the Observability chart on several clusters in one sitting is the
case that exposes a badly scoped guard, so treat it as a check rather than a
coincidence. Each upgrade restarts that cluster's collector, and while it
restarts the cluster reports nothing. Roll the clusters through close together
and their quiet windows overlap, leaving a period in which no cluster is
reporting at all. A guard scoped to the fleet cannot tell that period apart
from the object it protects having been deleted everywhere, so it pages during
what is a normal rollout. Read a policy or guard alert that arrives during a
multi-cluster upgrade, names no cluster, and clears on its own as a rule
scoped to the fleet rather than to a cluster. Confirm the object is present
before acting on it. For the Kyverno guards, kubectl get clusterpolicy on
each cluster settles it in one command. Collector restarts also make the
backlog land late, so the metric can read as continuous afterwards even though
the rule saw a gap while it evaluated. The stored history is therefore not
evidence that the alert was groundless, and the rule's own evaluation record is
the thing to check.
Expect the out-of-memory alert to stay quiet through the install itself, and treat it as real if it fires. It reports a pod terminated for memory pressure within the rule's recent window, so a stage that restarts platform components does not resurface terminations that already happened. Read a firing alert as a current termination to investigate rather than as deployment noise.
The rule asserts a recent termination, not the continued existence of the pod it names. A controller can replace an out-of-memory pod inside the same window, so a valid alert may point at a pod that is already gone. Investigate the owning workload, its replacement pod, and the termination timestamp, then review the memory limit for that workload.
The Observability chart installs in one of two modes, and the choice is per cluster. In its default mode it collects and stores locally, running the metrics, logs, traces, and profiles backends alongside the collector. In forwarding mode it runs the collector alone and sends each signal to another cluster's Observability release, which must have its authenticated OTLP receiver enabled and exposed through the ingress. Enable that receiver only on the cluster that stores, and give every installation a distinct deployment identity: it is the bounded label that separates telemetry after it converges, and a collision makes two installations operationally indistinguishable.
The Observability chart requires that identity and supplies no default for it.
Set global.dalpInstance to a stable slug that belongs to this installation
alone, and set global.deploymentEnvironment to one of local,
development, test, staging, demo, or production. The chart refuses to
render when either value is missing, and it refuses the reserved local slug in
any environment other than local.
The chart fails the render because the alternative is worse. Both values are stamped on every metric, log, trace, and profile the collector forwards, so a missing value that fell back to a default would produce a healthy-looking installation whose signals carry another installation's name. Two installations that share one slug merge into a single identity in the converged store: each dashboard instance selector offers one entry where there should be several, and each alert groups every deployment under the same label. Nothing reports an error in that state, because every signal still arrives. A refused render is a values correction before install; a shared identity is a silent loss of per-deployment visibility that persists until someone notices the estate looks smaller than it is.
The authenticated receiver and the forwarding path each need a credential, and
the Observability chart creates neither. Before you install, create two Secrets
in the namespace that holds the Observability release:
observability-receiver-basic-auth on the cluster that stores, and
observability-forwarding-basic-auth on each cluster that forwards. Each holds
a single password key. The chart passes them to the collector as environment
variables and writes no credential into its ConfigMap.
Set the username and create the matching Secret in the same change. A cluster
configured with a username but no Secret starts normally and reads as fully
configured, but its receiver fails closed and rejects every forwarded batch with
401 invalid credentials. Read that response as a missing or misnamed Secret on
the receiving cluster before you look at the sender. If you supply your own
alloy.alloy.extraEnv values, repeat the password entries the chart ships:
Helm replaces lists instead of merging them, and the chart fails the render
rather than let an enabled auth path lose its credential. Rotating either
credential needs an Alloy pod restart on the affected cluster, because the
config reloader watches only the ConfigMap.
Complete trace export and continuous profiling have separate release controls. Do not enable them from receiver health alone. The change window must include the accepted trace-load and profiler-overhead evidence for every shipped Node image, plus the emergency disable path. A missing capacity or overhead budget blocks enablement while the other signals continue to operate.
Verify a forwarded cluster by selecting its telemetry by its own cluster name rather than by checking that the sender reports success. Delivery and identity fail independently here: telemetry that is accepted but labelled with the receiving cluster's identity produces healthy counters on both ends while remaining unfindable for the cluster that produced it. If a newly connected cluster's name matches no stored telemetry, treat it as a labelling fault on the receiving side and do not restart the sender, which changes nothing.
The DALP chart is an umbrella chart. Environment values control which subcharts the deployment activates for the target cluster:
| Subchart | Purpose in the deployment | Enable when |
|---|---|---|
dapp | Console web application | Operators need the browser-based DALP console |
dapi | Explicit API, Workflow Engine runner, and Ledger Index Deployments | The Console, integrations, durable execution, or indexed reads run |
blockscout | Block explorer | Operators need an in-cluster explorer for the deployed EVM network |
docs | DALP documentation site | The environment hosts documentation with the platform release |
postgres-exporter | Server-side PostgreSQL metrics for the managed instance | You want backend counts and connection-ceiling headroom in dashboards |
The Workflow Engine and Ledger Index are mandatory role Deployments in the dapi subchart, not separate subcharts. Every DAPI role connects directly to PostgreSQL. Ordinary repository SQL flows through each pod's bounded application pool. Runner and indexer pods also carry native Effect Cluster ownership pools; API pods use the client-only layer and own no shard. Notification and health sessions are priced for the roles that open them. Before changing replicas, rollout overlap, or a pool cap, run the chart's connection-budget gate against the target PostgreSQL max_connections, non-DAPI reserve, and required free headroom. Ownership sessions are reserved for the life of an owning pod and never serve queries, so that path must stay session-stable and can never cross a transaction-mode pooler.
The timing that governs how long a lock operation may take before a pod concludes its shard-lock storage is unhealthy is fixed by the platform rather than exposed as a value, because it is only safe in combination with PostgreSQL holding the lock. The one shard setting you do choose is durable.sharding.shardsPerGroup, which sets how much durable work a pod gives up when it does lose its locks. Leave it at the shipped default unless replica counts change materially, and keep it identical on every pod: it is the modulus mapping work to a shard, so a pod using a different count addresses shards no pod owns and its sends are never picked up. Set it in the platform chart's shared values rather than per pod.
The budget model is per role. It adds each role's application pool and direct consumers, then multiplies that cost by the role's worst-case pod count, including surge and terminating-pod overlap. Raising API, runner, or indexer replica counts therefore consumes a different amount of budget. Do not tune indexer.backfill.workersPerChain as a database safety limit; it is a per-pod concurrency hint, and the indexer applies its own pool-wide cap inside the claim table. Request bursts inside one pod queue on that pod's own pool rather than on the server, so a passing gate bounds server connections, not peak request concurrency.
Ledger Index historical catch-up draws from the indexer role's application pool. Its pool-wide ceiling is indexer.backfill.maxInFlightClaimsPerChain, enforced inside the claim table across every indexer pod. Raise it when you want a reindex to finish faster; a pod that concentrates many claims spends its own pool first, so the pressure shows up as that pod's queue depth, not as extra server connections beyond its cap.
Choose the trusted edge profile with the route implementation. Envoy deployments use envoy; the bundled policy derives x-envoy-external-address from the preserved downstream TCP source rather than an inbound forwarding header. The bundled ingress-nginx profile uses nginx with use-forwarded-headers: "false" and compute-full-forwarded-for: "false", so the controller replaces client forwarding input with the request address it observes. OpenShift Routes use openshift with haproxy.router.openshift.io/set-forwarded-headers: append; DALP trusts only the terminal Router-added hop. Restrict the Console ingress policy to the selected controller namespace and DAPI ingress to the Console plus that controller namespace. Leave the profile at none when the controller contract is unknown; forwarding headers are then discarded instead of trusted.
The platform deploys no connection pooler and expects none. Every service connects directly with the configured datastore host, and the per-pod pools and the budget gate replace the capacity role a pooler served. If a managed database proxy already fronts PostgreSQL in your environment, point the datastore host at it and confirm it runs in session mode: the shard ownership path holds session advisory locks, and a transaction-mode proxy breaks that contract.
Recreate stays on the Deployments the budget and volume model price once: Blockscout, the PostgreSQL exporter, bundled PostgreSQL, Redis when persistence is enabled, and standalone object storage. Those charts keep a Recreate strategy. Blockscout upgrades clear legacy rolling-strategy state while preserving single-generation Recreate rollout. Do not change those workloads to RollingUpdate; re-run the connection-budget gate instead if capacity planning changes.
The Blockscout clear runs as a pre-upgrade job that calls the cluster API with the projected service account credentials the platform grants it. Upgrading a cluster that has run Blockscout before therefore needs cluster DNS or the API service address reachable from that job, and the service account token and cluster CA mounted into it. When the job cannot load those credentials it stops the upgrade and reports which file was missing. That is a failed step rather than a safe skip: legacy rolling parameters stay on the live workload and the next attempt fails the same way. Two conditions block the job in hardened clusters. Policy that requires pods to opt out of API access explicitly rejects a pod that opts in, so the platform grants the token on the job's service account instead of its pod. Policy or network rules that stop the job from reaching the API endpoint fail it outright. Grant that one job API access rather than relaxing the policy for every workload. Fresh installations skip the job because there is no prior strategy to clear.
Platform API and Console Deployments default to RollingUpdate. If you set their update strategy to Recreate, the chart ships a Recreate-only strategy so leftover rolling parameters cannot fail admission.
TLS to PostgreSQL is carried by the datastore sslMode, which renders into every service's connection URL. In this platform's driver, require verifies the server certificate and hostname against system CAs, which is stricter than the libpq meaning of require; use verify-ca or verify-full when you want the libpq-named verification levels stated explicitly. A server behind a private CA needs one extra step, because a URL sslmode parameter cannot carry CA material and takes precedence over the typed TLS configuration: leave the datastore sslMode empty, mount the CA file into the application pods, and set the DATABASE_TLS environment value to a JSON object with the verification mode and the CA path.
Network policies add one constraint for managed endpoints. When the PostgreSQL host is an IPv4 address, the charts render a matching egress rule automatically. Kubernetes NetworkPolicy cannot match DNS hostnames, so a managed endpoint that is only reachable by name needs an explicit egress entry with the endpoint's CIDR appended to each database-connected service's networkPolicy.egress values. Without that entry, DNS resolution succeeds but the database connection is denied.
Pool health is observable from the backend itself: each pod exports its application pool's in-use, idle, and queued-request gauges, and a sustained queue depth is the signal that distinguishes a saturated pool from a slow query. The postgres-exporter subchart adds the server-side view and ships disabled. It holds a direct session to the managed server, that session counts against the same PostgreSQL max_connections ceiling as everything else, and it draws from the reserve set aside for consumers outside the DALP backend. Enable it, or raise the connections it may open, only after re-running the chart's connection-budget gate for the target environment. Keep replicaCount at 1: the chart and budget gate fail closed above one replica, because Recreate only prevents generation overlap and does not price multi-replica sessions. The gate also rejects an enabled exporter whose maxConnections exceeds postgresConnectionBudget.nonDapiReserve. On clusters that source credentials from an external secret manager, the exporter needs an existing Secret supplied, because the chart renders no plaintext credentials there.
Environment wrapper charts, such as the local and staging charts, compose these groups into one installable release. A wrapper chart can also include an EVM network chart, such as a Besu stack, when the environment needs an in-cluster chain instead of an external network.
The platform routes outbound EVM JSON-RPC traffic through its in-platform RPC control plane rather than a separate gateway chart. Administrators configure each network's upstream RPC endpoints from the Console after deployment. See the Broadcast component page for how routing, health scoring, and failover work.
SettleMint confirms the final enabled chart set during environment planning. Each chart group has its own enabled flag. Managed PostgreSQL, Redis, object storage, observability, or chain infrastructure can replace the bundled chart where your environment provides that service.
Set a memory limit on every Bun workload you deploy, including the migration job. Bun uses JavaScriptCore rather than V8, so the chart does not inject Node heap flags; Kubernetes enforces the workload's cgroup limit directly.
All charts in a release share one version, and it is the same number as the platform release they deploy. That makes two checks cheap during an upgrade. Confirm the installed chart version matches the release you intended to deploy, and confirm the chart groups you upgraded now report the same version as each other. A group left behind reports the older number, which is how a partial upgrade becomes visible before it becomes a support case.
What can replace bundled services
DALP charts can deploy support services for self-hosted environments. The same charts can connect to managed services supplied by your infrastructure team. Before deployment starts, confirm credentials, network policy, and backup ownership.
| Area | Bundled option in the charts | Client-managed alternative |
|---|---|---|
| Datastores | PostgreSQL and Redis support charts | Managed PostgreSQL and Redis endpoints |
| Object storage | In-cluster object storage through the support charts | AWS S3, Azure Blob Storage, Google Cloud Storage, or S3-compatible object storage supplied by the environment |
| Ingress | Ingress or gateway components | Existing ingress controller, OpenShift Routes, or gateway |
| Backups | Backup tooling enabled through the support charts | Client backup platform and restore procedures |
| Chain access | Optional in-cluster EVM network chart for test use | External EVM network and RPC endpoints |
When your environment provides one of these services, SettleMint validates the connection details and deploys DALP with the bundled chart disabled for that service.
Stage 3: Post-deployment setup
After the charts are running, SettleMint connects the deployment to the blockchain network and finalizes application configuration.
- Deploy smart contracts and record addresses
- Validate Ledger Index connectivity and sync health
- Update application configuration with contract and endpoint references
- On an upgrade, confirm whether the release requires an index rebuild and, if so, that it has been started and is draining
When this stage completes, the platform is fully wired to the blockchain network. All contract addresses and endpoint references are in place and ready for use.
Background cadences ship as deployment values rather than as code. The chain
health poll interval is monitoring.blockchainHealthCollector.intervalSeconds
and defaults to 60 seconds. Lower values must divide 60. The per-chain
transaction confirmation tick is durable.confirmationWatcher.intervalMs. It
defaults to 250 ms and is bounded from 50 ms to 60 s. The derived-measures drain
interval and per-pass row ceiling are under indexer.derivedMeasures. The
defaults are deployment-ready. If an environment needs a different polling
budget, set these values during this stage. A rate-limited RPC endpoint is one
example. Do not patch the workload later. The application validates the
documented bounds at startup.
Adding a network after handoff
The networks a deployment serves do not all have to be declared before installation. The deployed configuration carries a baseline set, and a platform administrator can register, change, or remove a network afterwards through the Platform API or the CLI. That change takes effect without a redeploy: the replica handling the write applies it before answering, and the other replicas pick it up over a PostgreSQL notification.
Three limits apply, and it is worth knowing them before planning a network addition rather than discovering them during one.
- The default network stays in configuration. A runtime entry can never set the default flag. Changing which network is the default is a values change and a release.
- A network in use cannot be removed or disabled. If organisation systems are deployed on a chain and the change would leave that chain with no enabled network, the platform refuses and names the network at fault. Remove or migrate the systems first.
- Endpoints do not travel with a chain change. If endpoint entries exist for a network, moving it to a different chain id is refused. Delete the endpoints and resubmit them for the new chain, so nothing inherits a verification result from the chain the network used to be.
A network registered this way is reported as database-sourced on the admin list, which is the way to tell it apart from one declared in the deployed values during a later configuration review. Fold that distinction into the handoff configuration reference whenever a network is added after installation, or the next upgrade will read the runtime additions as undocumented drift.
Recording the Directory address, and changing it later
"Deploy smart contracts and record addresses" above has one entry that is more load bearing than the rest: the Directory address on the network entry. Every other contract the environment uses (systems, registries, identity factories) is reached through it, so the environment is only as well defined as that single value.
Record exactly one Directory address per chain. A chain can physically hold more than one Directory generation, and the index will record each of them; the configured address is what makes one of them this environment's. An entry that names none does not fall back to a sibling entry's Directory, and two enabled entries on one chain that name different Directory addresses are refused with both addresses shown. A configuration mistake here thus surfaces at install, rather than as attribution failures months later.
Changing that address after handoff is not in the same class as adding a network. Upgrading the Directory in place, at the same address, is routine and needs nothing here. Pointing the environment at a Directory deployed at a new address is a data migration: the contracts already deployed keep resolving through the old address, and the configuration change moves none of them. It requires privileged approval bound to the environment and chain, on-chain verification of the target, a migration for the existing contract population, quiescence of write traffic, a reindex, and a convergence check before traffic resumes. Plan it as a maintenance window with a rollback address written down, and follow the directory re-point runbook rather than treating it as a values edit.
Two alerts back this after handoff: one fires when a chain is serving more than one indexed Directory generation, the other when an identity is registered that cannot be attributed to any indexed factory. Confirm both are evaluating for the install during Stage 4. While the emitting metric has not reached an environment, both alerts resolve as healthy, which is indistinguishable from working.
Stage 4: Verification and handoff
SettleMint and the client team verify health, security, and operational readiness before handoff. This stage covers route validation, observability, and backup readiness.
- Validate ingress routes, TLS, and authentication
- Confirm the native V2 Start Here dashboard, every folder and drilldown, and all four local backend queries
- Confirm each forwarded signal has both local and central receipt under the same deployment identity
- Keep replacement rules shadow-owned through forced failure and recovery, then switch notification ownership separately and prove exactly one owner
- Register every cluster expected to report telemetry into this install, so the platform alerts when one stops reporting
- Verify backup configuration and restore readiness
Dashboard rollback never restores telemetry data. Retain the last-known-good chart release and its exact resource manifest, and preserve backend storage through the rollout. If navigation, queries, or notification routing regress, roll back the release; the restored dashboards and rules must query the same stored metrics, logs, traces, and profiles without a conversion step.
Registering the reporting clusters is a required step rather than a tuning option. Alert rules resolve to a healthy state when no matching data exists, which keeps rules that do not apply to your install quiet, but it also means a cluster that stops sending telemetry suppresses its own alerts instead of raising them. The observability chart derives one absence alert per registered cluster, and that list is the only place the platform learns which clusters are supposed to be reporting. A cluster left unregistered is unmonitored in a way that looks identical to a healthy one.
Some alert rules ship disabled because the metrics they read exist on only one cluster in a fleet. Enable those on the install whose dashboards read the metric store that receives them, which is not necessarily the cluster the metrics come from. Leaving them enabled everywhere fills each environment's alert list with rules that can never fire.
When this stage completes, you receive a working platform with verified endpoints and access details. The handoff includes all admin credentials, contract addresses, and the configuration reference for future upgrades.
If the client must run the platform deployment
SettleMint can support client-led deployment in exceptional cases, but the post-deployment setup remains SettleMint-owned. Contact your SettleMint representative before planning a client-led deployment.
Required tooling and access
- Helm version 3.x and kubectl (or oc CLI on OpenShift) configured for the target cluster
- Ability to install CRDs, IngressClass (or Routes on OpenShift), and namespace-scoped resources
- Harbor credentials and egress access to harbor.settlemint.com
- Access to managed service credentials and TLS certificates
Required inputs
- Final FQDN list for enabled routes
- TLS certificates and private keys for each route
- PostgreSQL, Redis, and object storage connection details
- The Redis certificate authority bundle, when the cache endpoint presents a certificate issued by a private authority
- Approval for any operator CRDs required by the charts
Cache transport trust
Enabling TLS for the cache selects an encrypted connection. The platform then verifies the endpoint certificate against the trust store the container image carries. A certificate issued by a private authority is not in that store, so the connection is refused and no other setting recovers it.
Supply the authority bundle with the cache settings when your endpoint uses a private authority. Supply the expected certificate name as well when the certificate does not name the address the platform dials, which happens with a shared endpoint or a rewritten service address.
Certificate verification stays enabled by default. Provide the authority bundle rather than disabling verification: disabling it accepts any certificate and removes the protection the encrypted connection exists to give.
Handoff package
You receive the following after installation:
- Application and API endpoint inventory
- Admin credentials for enabled services
- Deployed contract addresses and network references
- Ledger Index endpoint information and sync status
- Configuration reference for future upgrades
Post-installation support
Support response and incident handling depend on your contracted SLA tier. SettleMint provides upgrade guidance and remediation for DALP components within the agreed support scope.
Timeline expectations
| Phase | Typical duration |
|---|---|
| Pre-installation verification | 1 to 2 business days |
| Platform deployment | 1 to 2 business days |
| Post-deployment setup | 4 to 8 hours |
| Verification and handoff | 2 to 4 hours |
| Total | 2 to 4 business days |
See also
- Prerequisites for infrastructure requirements
- High availability for HA and DR configurations
- DALP Workflow Engine for component architecture
Prerequisites - Self-hosting infrastructure requirements
Infrastructure, service, network, and credential checklist for teams preparing a self-hosted DALP installation on Kubernetes or OpenShift.
OpenShift installation guide
OpenShift deployment guidance for self-hosted DALP environments that use restricted SCCs, Routes, and OpenShift Data Foundation or another CSI-backed storage class.