Minimal Docker Compose, Canton config, and Canton bootstrap for 3.x?

I am assembling a Canton 3.x-based Docker Compose for experimentation, testing, and demos. I just need a local synchronizer – not a connection to the Global Synchronizer. I don’t need the validator app or a wallet.

What is the minimal Docker Compose, Canton config, and Canton bootstrap to do this?

Here is a bootstrap that works with 3.2:
(3.2.0-snapshot.20241217.14528.0.v538e5faf)

import com.digitalasset.canton.console.LocalInstanceReference
import com.digitalasset.canton.domain.config.DomainParametersConfig
import com.digitalasset.canton.version.ProtocolVersion

val sequencer = sequencers.local.head
val mediator = mediators.local.head
val participant = participants.local.head

def staticParameters(sequencer: LocalInstanceReference) =
  DomainParametersConfig(alphaVersionSupport = true)
    .toStaticDomainParameters(sequencer.config.crypto, ProtocolVersion.v32)
    .map(StaticDomainParameters(_))
    .getOrElse(sys.error("Getting staticParameters failed."))

com.digitalasset.canton.console.EnterpriseConsoleMacros.bootstrap.domain(
  "domain",
  domainOwners = Seq(sequencer),
  sequencers = Seq(sequencer),
  mediators = Seq(mediator),
  domainThreshold = PositiveInt.one,
  staticDomainParameters = staticParameters(sequencer)
)

participant.domains.connect(sequencer, "domain")

Here is what I have for 3.3:
(3.3.0-snapshot.20250425.15794.0.v8777d491):

import com.digitalasset.canton.console.LocalInstanceReference
import com.digitalasset.canton.synchronizer.config.SynchronizerParametersConfig
import com.digitalasset.canton.admin.api.client.data.StaticSynchronizerParameters
import com.digitalasset.canton.version.ProtocolVersion

val sequencer = sequencers.local.head
val mediator = mediators.local.head
val participant = participants.local.head

def staticParameters(sequencer: LocalInstanceReference) =
  SynchronizerParametersConfig(alphaVersionSupport = true)
    .toStaticSynchronizerParameters(sequencer.config.crypto, ProtocolVersion.v33)
    .map(StaticSynchronizerParameters(_))
    .getOrElse(sys.error("Getting staticParameters failed."))

bootstrap.synchronizer(
  "domain",
  synchronizerOwners = Seq(sequencer),
  sequencers = Seq(sequencer),
  mediators = Seq(mediator),
  synchronizerThreshold = PositiveInt.one,
  staticSynchronizerParameters = staticParameters(sequencer)
)

participant.synchronizers.connect(sequencer, "domain")

Here is one for 3.4:
(3.4.0-snapshot.20250422.15819.0.vb4694722):

import com.digitalasset.canton.console.LocalInstanceReference
import com.digitalasset.canton.synchronizer.config.SynchronizerParametersConfig
import com.digitalasset.canton.admin.api.client.data.StaticSynchronizerParameters
import com.digitalasset.canton.version.ProtocolVersion

val sequencer = sequencers.local.head
val mediator = mediators.local.head
val participant = participants.local.head

def staticParameters(sequencer: LocalInstanceReference) =
  SynchronizerParametersConfig(alphaVersionSupport = true)
    .toStaticSynchronizerParameters(sequencer.config.crypto, ProtocolVersion.v34)
    .map(StaticSynchronizerParameters(_))
    .getOrElse(sys.error("Getting staticParameters failed."))

bootstrap.synchronizer(
  "domain",
  synchronizerOwners = Seq(sequencer),
  sequencers = Seq(sequencer),
  mediators = Seq(mediator),
  synchronizerThreshold = PositiveInt.one,
  staticSynchronizerParameters = staticParameters(sequencer)
)

participant.synchronizers.connect(sequencer, "domain")
sample docker-compose.yaml
services:

  canton:
    container_name: canton
    image: digitalasset-docker.jfrog.io/canton-enterprise:3.2.0-snapshot.20241217.14528.0.v538e5faf
    volumes:
      - ./configs:/canton/host/configs
    command: >
      daemon
      --config "/canton/host/configs/canton.conf"
      --bootstrap "/canton/host/configs/bootstrap.canton"
      --log-profile container
    expose:
      - 5001
      - 5002
      - 5007
      - 5008
      - 5009
    ports:
      - 5001:5001
      - 5002:5002

  console:
    container_name: console
    image: digitalasset-docker.jfrog.io/canton-enterprise:3.2.0-snapshot.20241217.14528.0.v538e5faf
    volumes:
      - ./configs:/canton/host/configs
    command: >
      --no-tty
      --config "/canton/host/configs/console.conf"
      --log-profile container
      --log-level-root WARN
sample configs/canton.conf
canton {
  mediators {
    mediator {
      admin-api.address = 0.0.0.0
      admin-api.port = 5007
    }
  }
  sequencers {
    sequencer {
      public-api.address = 0.0.0.0
      public-api.port = 5008
      admin-api.address = 0.0.0.0
      admin-api.port = 5009
    }
  }
  participants {
    participant {
      ledger-api.address = 0.0.0.0
      ledger-api.port = 5001
      admin-api.address = 0.0.0.0
      admin-api.port = 5002
    }
  }
}
sample configs/console.conf
canton {
  features.enable-testing-commands = yes
  remote-mediators {
    mediator {
      admin-api.address = canton
      admin-api.port = 5009
    }
  }
  remote-sequencers {
    sequencer {
      public-api.address = canton
      public-api.port = 5008
      admin-api.address = canton
      admin-api.port = 5009
    }
  }
  remote-participants {
    participant {
      ledger-api.port = 5001
      ledger-api.address = canton
      admin-api.port = 5002
      admin-api.address = canton
    }
  }
}
sample commands
docker compose up --detach canton

docker compose run -it --rm console

This is all being assembled before the docs, so very open to suggestions!

1 Like