I’ve been trying to set up a docker-compose which assembles each component of Canton OSS (Sequencer, Mediator and Participant) as separate services.
I’ve managed to create a structure which has one Dockerfile for each component and respective conf file. The bootstrap/init files are still in the works, while trying to leverage on the console to build them, but the rest seems to be working standalone. However, I’m facing challenges finding the right way to connect all of these components together.
One such oddities is the following:
The mediator I’ve setup is not called mediator1 nor is it supposed to be connected to a local sequencer or a sandbox participant. These values make little sense given what I’ve configured and I’m wondering whether something is being overriden or how I should interpret these results.
Please note that so far the bootstrap files only have the following line
nodes.local.start()
I’ve also tried to connect with a remote configuration instead of using the sandbox-console and then when trying to list nodes I’m getting the same results.
I’ve also seen a few discrepancies between documentation and the config files under the canton release. E.g. there are references of a manager.conf in some docs ( Install Canton — Daml SDK 2.10.2 documentation , Install Canton — Digital Asset’s platform documentation) which I assume referred to the topology manager, yet the sample config files from the release zip or tar.gz seem to have no mention on them. I’m wondering if they’re needed or not.
I’ll post below a few of the snippets of code I’ve been running and any support or clarification on how to complete this setup, or whether this is not possible on OSS, is welcome.
Dockerfile.mediator
# Canton Domain Dockerfile (Mediator)
FROM eclipse-temurin:21-jdk-jammy
# Install dependencies
RUN apt-get update && apt-get install -y \
curl \
wget \
unzip \
&& rm -rf /var/lib/apt/lists/*
# Download and install Canton
ARG CANTON_VERSION=3.4.7
WORKDIR /opt
RUN wget https://github.com/digital-asset/canton/releases/download/v${CANTON_VERSION}/canton-open-source-${CANTON_VERSION}.tar.gz && \
tar -xzf canton-open-source-${CANTON_VERSION}.tar.gz && \
mv canton-open-source-${CANTON_VERSION} canton && \
rm canton-open-source-${CANTON_VERSION}.tar.gz
# Create Canton directories
RUN mkdir -p /canton/config /canton/init /canton/data
# Copy configuration files
COPY config/mediator.conf /canton/config/
# Set permissions
RUN chmod -R 755 /canton
WORKDIR /canton
# Expose ports
# 10042 - Admin API
# 10043 - grpc-health-server
# 10044 - http-health-server
EXPOSE 10042 10043 10044
# Start Canton domain with configuration
CMD ["/opt/canton/bin/canton", "daemon", "-c", "/canton/config/mediator.conf", "--bootstrap", "/canton/init/mediator.canton"]
mediator.conf
include required("shared.conf")
canton.mediators.mediator {
storage = ${_shared.storage}
storage.config.properties.databaseName = "canton_mediator"
admin-api {
address = 0.0.0.0
port = 10042
}
monitoring {
grpc-health-server {
address = 0.0.0.0
port = 10043
}
http-health-server {
address = 0.0.0.0
port = 10044
}
}
}
Dockerfile.sequencer
# Canton Domain Dockerfile (Sequencer)
FROM eclipse-temurin:21-jdk-jammy
# Install dependencies
RUN apt-get update && apt-get install -y \
curl \
wget \
unzip \
&& rm -rf /var/lib/apt/lists/*
# Download and install Canton
ARG CANTON_VERSION=3.4.7
WORKDIR /opt
RUN wget https://github.com/digital-asset/canton/releases/download/v${CANTON_VERSION}/canton-open-source-${CANTON_VERSION}.tar.gz && \
tar -xzf canton-open-source-${CANTON_VERSION}.tar.gz && \
mv canton-open-source-${CANTON_VERSION} canton && \
rm canton-open-source-${CANTON_VERSION}.tar.gz
# Create Canton directories
RUN mkdir -p /canton/config /canton/init /canton/data
# Copy configuration files
COPY config/sequencer.conf /canton/config/
# Set permissions
RUN chmod -R 755 /canton
WORKDIR /canton
# Expose ports
# 10038 - Public API
# 10039 - Admin API
# 10033 - grpc-health-server
# 10034 - http-health-server
EXPOSE 10038 10039 10033 10034
# Start Canton domain with configuration
CMD ["/opt/canton/bin/canton", "daemon", "-c", "/canton/config/mediator.conf", "--bootstrap", "/canton/init/sequencer.canton"]
sequencer.conf
include required("shared.conf")
canton.sequencers.sequencer {
storage = ${_shared.storage}
storage.config.properties.databaseName = "canton_sequencer"
public-api {
address = 0.0.0.0
port = 10038
}
admin-api {
address = 0.0.0.0
port = 10039
}
sequencer {
type = BFT
block {
writer = ${?_shared.sequencer-writer}
reader = ${?_shared.sequencer-reader}
writer.type = high-throughput
}
}
monitoring {
grpc-health-server {
address = 0.0.0.0
port = 10033
}
http-health-server {
address = 0.0.0.0
port = 10034
}
}
}
docker-compose.yml
services:
# PostgreSQL database for Canton
postgres:
image: postgres:17.6
container_name: retvn-postgres
environment:
POSTGRES_DB: canton
POSTGRES_USER: canton
POSTGRES_PASSWORD: *****
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./docker/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U canton"]
interval: 10s
timeout: 5s
retries: 5
networks:
- retvn-network
# Canton sequencer (sequencer)
canton-sequencer:
build:
context: ./docker/canton
dockerfile: Dockerfile.sequencer
container_name: retvn-canton-sequencer
ports:
- 10038:10038 # Public API
- 10039:10039 # Admin API
- 10033:10033 # grpc-health-server
- 10034:10034 # http-health-server
environment:
CANTON_DB_HOST: postgres
CANTON_DB_PORT: 5432
CANTON_DB_NAME: canton-sequencer
CANTON_DB_USER: canton
CANTON_DB_PASSWORD: *****
volumes:
- ./docker/canton/config:/canton/config
- ./docker/canton/init:/canton/init
- canton_domain_data:/canton/data
depends_on:
postgres:
condition: service_healthy
networks:
- retvn-network
# Canton mediator (mediator)
canton-mediator:
build:
context: ./docker/canton
dockerfile: Dockerfile.mediator
container_name: retvn-canton-mediator
ports:
- 10042:10042 # Admin API
- 10043:10043 #
- 10044:10044 #
environment:
CANTON_DB_HOST: postgres
CANTON_DB_PORT: 5432
CANTON_DB_NAME: canton-mediator
CANTON_DB_USER: canton
CANTON_DB_PASSWORD: *****
volumes:
- ./docker/canton/config:/canton/config
- ./docker/canton/init:/canton/init
- canton_domain_data:/canton/data
depends_on:
postgres:
condition: service_healthy
networks:
- retvn-network
volumes:
postgres_data:
driver: local
canton_domain_data:
driver: local
networks:
retvn-network:
driver: bridge
