Skip to main content

Documentation Index

Fetch the complete documentation index at: https://cantonfoundation-issue-365-details-history.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

This page walks through deploying a Canton Network validator using Docker Compose. For Kubernetes, see Kubernetes Validator Deployment.

Before you begin

Confirm that you have completed the onboarding process and have the following ready:
  • Your static egress IP is allowlisted
  • You have an onboarding secret from your SV sponsor (or self-generated for DevNet)
  • You know the sponsor SV URL
  • You have the current migration ID (published at sync.global/sv-network/)
  • You have chosen a party hint for your validator admin (format: organization-function-enumerator, for example acmeCorp-validator-1)

Download the Splice node bundle

Both deployment methods start by downloading the release bundle from GitHub:
# Replace the version with the current release
export SPLICE_VERSION=0.5.12

curl -LO https://github.com/digital-asset/decentralized-canton-sync/releases/download/v${SPLICE_VERSION}/${SPLICE_VERSION}_splice-node.tar.gz

tar xzvf ${SPLICE_VERSION}_splice-node.tar.gz
The extracted bundle contains Docker Compose files, sample Helm values, and configuration templates.

Docker Compose installation

1. Navigate to the validator directory

cd splice-node/docker-compose/validator

2. Set the image tag

export IMAGE_TAG=${SPLICE_VERSION}

3. Start the validator

./start.sh \
  -s "<SPONSOR_SV_URL>" \
  -o "<ONBOARDING_SECRET>" \
  -p "<PARTY_HINT>" \
  -m "<MIGRATION_ID>" \
  -w
The -w flag enables the Wallet UI. Add -a to enable authentication (recommended for anything beyond local testing). On subsequent restarts, you can omit the -o flag since the onboarding secret is consumed on first use:
./start.sh \
  -s "<SPONSOR_SV_URL>" \
  -p "<PARTY_HINT>" \
  -m "<MIGRATION_ID>" \
  -w

4. Verify the deployment

After startup completes, access the web UIs: Check the logs for successful onboarding:
docker compose logs -f validator
Look for messages indicating the validator has connected to the synchronizer and completed onboarding.

5. Stop the validator

./stop.sh

Systemd integration

For persistent deployments, create a systemd service. Set RemainAfterExit=true since start.sh runs Docker Compose in detached mode:
[Unit]
Description=Canton Network Validator
After=docker.service
Requires=docker.service

[Service]
Type=oneshot
RemainAfterExit=true
WorkingDirectory=/path/to/splice-node/docker-compose/validator
ExecStart=/path/to/splice-node/docker-compose/validator/start.sh -s "<SV_URL>" -p "<PARTY_HINT>" -m "<MIGRATION_ID>" -w
ExecStop=/path/to/splice-node/docker-compose/validator/stop.sh

[Install]
WantedBy=multi-user.target
This section was copied from existing reviewed documentation. Source: splice:docs/src/validator_operator/validator_compose.rst Reviewers: Skip this section. Remove markers after final approval.
This section describes how to deploy a standalone validator node on a VM or a local machine using Docker Compose. The deployment consists of the validator node along with associated wallet and CNS UIs, and onboards the validator node to the target network. This deployment is useful for:
  • Application development, where one needs an ephemeral validator that is easy to deploy.
  • Production validators, with the following caveats:
    • The default deployment is highly insecure. Authentication should be enabled as described in the authentication section.
    • There is no support for ingress from outside your machine, nor is there support for TLS. The deployment should be kept local to your machine only and not exposed externally.
    • Reliability & scalability: docker-compose will restart containers that crash, and the deployment supports backup&restore as detailed below, but a docker-compose deployment is inherently more limited than a cloud-based Kubernetes one.
    • Monitoring: The deployment, as opposed to a Kubernetes-based one, does not include monitoring.
    • For production settings, you should aim to keep your validator up and running constantly, in order to avoid losing out on rewards, and avoid issues with catching up on ledger state after significant downtime.

Requirements

  1. A linux/MacOS machine with the following:
    1. docker compose - at least version 2.26.0 or newer
    2. curl
    3. jq
    Note that both AMD64 and ARM64 architectures are supported.
To validate that the dependencies are set up correctly, run the following commands. All commands should succeed and print out the version. Note that the exact versions you see may be different from the example here. As long as you have docker-compose 2.26.0 or newer you should be fine.
> docker compose version
Docker Compose version 2.32.1
> curl --version
curl 8.11.0 (x86_64-pc-linux-gnu) libcurl/8.11.0 OpenSSL/3.3.2 zlib/1.3.1 brotli/1.1.0 zstd/1.5.6 libidn2/2.3.7 libpsl/0.21.5 libssh2/1.11.1 nghttp2/1.64.0
Release-Date: 2024-11-06
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd
> jq --version
jq-1.7.1
  1. Your machine should either be connected to a VPN that is whitelisted on the network (contact your sponsor SV to obtain access), or have a static egress IP address. In the latter case, please provide that IP address to your sponsor SV to add it to the firewall rules.
  2. Please download the release artifacts containing the docker-compose files, from here: , and extract the bundle:
tar xzvf _splice-node.tar.gz Additional parameters describing your own setup as opposed to the connection to the network are described below.

HTTP Proxy configuration

If you need to use an HTTP forward proxy for egress in your environment, you need to set https.proxyHost and https.proxyPort in JAVA_TOOL_OPTIONS in splice-node/docker-compose/validator/compose.yaml to use the HTTP proxy for outgoing connections. You need to do this for both the validator and the participant services:
services:
  validator:
    environment:
      JAVA_TOOL_OPTIONS: >-
        -Dhttps.proxyHost=your.proxy.host
        -Dhttps.proxyPort=your_proxy_port
services:
  participant:
    environment:
      JAVA_TOOL_OPTIONS: >-
        -Dhttps.proxyHost=your.proxy.host
        -Dhttps.proxyPort=your_proxy_port
Replace your.proxy.host and your_proxy_port with the actual host and port of your HTTP proxy. You can set https.nonProxyHosts as well to prevent proxying for particular addresses. Proxy authentication is currently not supported.

Deployment

  1. Change to the docker-compose directory inside the extracted bundle:
cd splice-node/docker-compose/validator
  1. Export the current version to an environment variable:
  2. Run the following command to start the validator node, and wait for it to become ready (could take a few minutes):
./start.sh -s "&lt;SPONSOR_SV_URL&gt;" -o "&lt;ONBOARDING_SECRET&gt;" -p "&lt;party_hint&gt;" -m "&lt;MIGRATION_ID&gt;" -w
```text

Where:

`&lt;party_hint&gt;` will be used as the prefix of the Party ID of your validator's administrator.
This must be of format `\<organization\>-\<function\>-\<enumerator\>`, e.g. `myCompany-myWallet-1`. It cannot be changed over time as it is part of the validator operator party ID.
Note that the validator may be stopped with the command ./stop.sh and restarted again with the same start.sh command as above. Its data will be retained between invocations. In subseqent invocations, the secret itself may be left empty, but the -o is still mandatory, so a -o "" argument should be provided.

Logging into the wallet UI

Docker Compose-based validator deployments use .localhost subdomains for addressing, such as wallet.localhost. .localhost URLs reportedly do not work on some browsers. If you encounter issues please try using a different browser such as Firefox or Chrome. If you’re encountering issues with reaching APIs from a custom program or script, you may need to set the HOST header on HTTP requests explicitly to the target .localhost address.
The wallet UI is accessible at http://wallet.localhost in your browser. The validator administrator’s username is administrator. Insert that name into the username field and click Log in, and you should see the wallet of the administrator of your wallet. You can also logout of the administrator account and login as any other username. The first time a user logs in, they will be prompted with a message asking them to confirm whether they wish to be onboarded to the validator node. link to section that explains what this onbarding means

Logging into the CNS UI

You can open your browser at http://ans.localhost (note that this is currently by default ans and not cns), and login using the same administrator user, or any other user that has been onboarded via the wallet, in order to purchase a CNS entry for that user.

Accessing the Canton Participant APIs

The JSON Ledger API is exposed under json-ledger-api.localhost:80. Note that for some clients you may explicitly need to set the Host: json-ledger-api.localhost header for this to get resolved correctly. The gRPC Ledger API is exposed under grpc-ledger-api.localhost:80. Note that for some clients you may explicitly need to set the :authority: json-ledger-api.localhost pseudo-header for this to get resolved correctly. The Canton Admin API is not exposed by default as it does not yet support auth. There is a commented out section in nginx.conf that you can enable to expose it if you ensure that it is not exposed publicly, e.g., through network restrictions.

Configuring Authentication

The default deployment uses highly insecure self-signed tokens. Anyone with access to the wallet UI (or the machine and/or its network interface) may log in to your wallet as a user of their choice. For any production use, you should configure proper authentication as described in this section.
Please refer to the authentication section for instructions on how to set up an OAuth provider for your validator. The URLs to configure for callbacks are http://wallet.localhost and http://ans.localhost. Once you have set up your OAuth provider, you need to configure it by setting the following environment variables in the .env file:
NameValue
AUTH_URLThe URL of your OIDC provider for obtaining the openid-configuration and jwks.json.
AUTH_JWKS_URLThe URL of your OIDC provider for obtaining the jwks.json, will typically be ${AUTH_URL}/.well-known/jwks.json.
AUTH_WELLKNOWN_URLThe URL of your OIDC provider for obtaining the openid-configuration, will typically be ${AUTH_URL}/.well-known/openid-configuration.
LEDGER_API_AUTH_AUDIENCEThe audience for the participant ledger API. e.g. https://ledger_api.example.com. This will set the ledger-api.auth-services.target-audience configuration for the participant.
LEDGER_API_AUTH_SCOPEThe scope for the participant ledger API. This will set the participant’s ledger-api.auth-services.target-scope configuration. Optional
VALIDATOR_AUTH_AUDIENCEThe audience for the validator backend API. e.g. https://validator.example.com.
VALIDATOR_AUTH_CLIENT_IDThe client id of the OAuth app for the validator app backend.
VALIDATOR_AUTH_CLIENT_SECRETThe client secret of the OAuth app for the validator app backend.
LEDGER_API_ADMIN_USERShould match the sub field of JWTs issued for the validator app. For some auth providers, this would be formed as CLIENT_ID@clients.
WALLET_ADMIN_USERThe user ID of the user which should login as the wallet administrator. Note that this should be the full user id, e.g., `auth043b68e1e4978b000cefba352, *not* only the suffix 43b68e1e4978b000cefba352`.
WALLET_UI_CLIENT_IDThe client id of the OAuth app for the wallet UI.
ANS_UI_CLIENT_IDThe client id of the OAuth app for the CNS UI.
CONTACT_POINTThe contact point for your validator node that can be used by other node operators to reach out to you if needed (slack username or an email address). Optional
In order to enable auth in the deployment, add the -a flag to the start.sh command, as follows:
./start.sh -s "&lt;SPONSOR_SV_URL&gt;" -o "&lt;ONBOARDING_SECRET&gt;" -p "&lt;party_hint&gt;" -m "&lt;MIGRATION_ID&gt;" -w -a
If you have already deployed a non-authenticated validator on your machine, you can migrate it to an authenticated one by stopping the validator with ./stop.sh and restarting it with the -a flag as above. The validator operator user will be automatically migrated, and the user indicated by the WALLET_ADMIN_USER variable will be associated with the validator operator party. If you have also onboarded other users onto your validator, those will not be automatically migrated, and you need to manually associate the OAuth users with their corresponding parties. In order to do that, first take note of the party IDs of all relevant users (do this before stopping the unauthenticated validator), e.g. by copying them from the top-right corner of their wallet UIs. Now for every user that you wish to migrate, follow the instructions for associating a user with a party in the Users, Parties and Wallets in the Splice Wallet section, but replace the admin party ID with the party ID which you wish to associate with each user.

Configuring Automatic Traffic Purchases

Your node is configured to automatically purchase traffic on a pay-as-you-go basis (see automatically purchase traffic). To tune to your needs, you can set environment variables, for example:
export TARGET_TRAFFIC_THROUGHPUT=20000 # target throughput in bytes/second
export MIN_TRAFFIC_TOPUP_INTERVAL="1m" # minimum interval between top-ups

Integration with systemd and other init systems

If you want to manage the validator through systemd or a similar init system, create a service that calls the start.sh script with the right arguments. However, note that start.sh invokes docker compose up with the -d/--detach option so the script exits after the containers are up instead of continuing running. You need to make sure that your service does not stop docker compose at that point. To accomplish this with systemd set RemainAfterExit=true. Refer to the systemd documentation for more details. If you are using another init system, look for similar options to ensure that docker compose continues running after the script exits. Alternatively, you can edit the script to remove the -d option so the script continues running.

First startup verification checklist

After deploying with either method, verify:
  • Validator logs show successful connection to the Global Synchronizer sequencer
  • The onboarding process completed without errors
  • The Wallet UI loads and displays your validator identity
  • Your party hint appears correctly in the validator admin party
  • Traffic auto-top-up is functioning (if configured)
If startup fails with connection errors, verify that your egress IP is allowlisted and that outbound HTTPS (port 443) is permitted to *.sync.global endpoints.

Next steps

Configuration

Tune your validator’s configuration.

Authorization Setup

Configure authentication for production use.