On-Premise installation
HA and Scaling
Run Carbone On-Premise as a cluster for high availability and conversion load balancing
Overview
Carbone On-Premise scales horizontally as a cluster of nodes (or Docker containers) with no single point of failure. On top of template management, a cluster gives you:
- High availability: nodes replicate their template metadata conflict-free, so any node can start or stop without losing data.
- Job balancer: idle nodes pull document conversion jobs from busy nodes, smoothing out conversion spikes without an external load balancer.
- Monitoring: track replication and conversion activity on the Prometheus-compatible
/metricsendpoint.
High availability and clustering
Carbone runs across a cluster of nodes or Docker containers with no single point of failure: nodes replicate their template metadata conflict-free and persist it to a shared /template volume or external storage, so they can start and stop dynamically without losing data.
Set up the cluster on each node in three steps:
- Enable template management, which provides the metadata database and the cluster channel.
- Open the internal cluster port with
peerPort. - Declare the other nodes with
peerEndpoints.
export CARBONE_TEMPLATE_MANAGEMENT=true
export CARBONE_PEER_PORT=5001
export CARBONE_PEER_ENDPOINTS=node-b:5001,node-c:5001
| Env. Variable | config.json parameter | Default value | Description |
|---|---|---|---|
CARBONE_PEER_PORT |
peerPort |
Port for conflict-free synchronisation between nodes. | |
CARBONE_PEER_ENDPOINTS |
peerEndpoints |
Comma-separated addresses of the other cluster peers. Each entry is a hostname (domain name, Docker container name, or Kubernetes service name) or an IP address, optionally with :port (no ws:// needed). Carbone resolves each hostname through DNS and uses every returned IP as a peer, so a headless Kubernetes service expands to all its pods. Without a port, it reuses peerPort. |
|
CARBONE_TEMPLATE_METADATA_FLUSH_CRON |
templateMetadataFlushCron |
0 0 * * * |
How often the elected leader (the oldest peer) persists the metadata to disk and external storage. |
CARBONE_TEMPLATE_METADATA_FLUSH_ON_EXIT |
templateMetadataFlushOnExit |
true | Flush the metadata when a node shuts down. |
CARBONE_TEMPLATE_METADATA_PATCH_RETENTION_HOURS |
templateMetadataPatchRetentionHours |
25 | How long each node keeps the synchronisation patch sets used to catch up peers. Must be greater than the time between two flushes. |
Once configured, replication is automatic:
Startup: a node loads the latest flushed metadata (.metadata.db.0, falling back to .metadata.db.1), then fetches any missing events from its peers. The HTTP server starts only once synchronisation is complete.
Shutdown: the leader flushes the metadata (per the cron, or on exit when templateMetadataFlushOnExit=true), copying the current file to .metadata.db.1 before overwriting .metadata.db.0. A non-leader node first ensures its local changes are synchronised, then exits.
Job balancer
The job balancer spreads document conversion load across the peers of a cluster. When one peer is overloaded and another is idle, the idle peer automatically pulls pending conversion jobs from the busy peer, runs them locally, and returns the result. This smooths out conversion spikes without any external load balancer: you do not need to route render requests to a specific node.
Available since v5.9.1. The job balancer is disabled by default.
Once your cluster is configured (above), the job balancer only needs one extra flag on each node:
export CARBONE_JOB_BALANCER=true
| Env. Variable | CLI option | config.json parameter | Default value |
|---|---|---|---|
CARBONE_JOB_BALANCER |
N/A | jobBalancer |
false |
How it works. Each peer periodically broadcasts the size of its conversion queue to the other peers. A peer that has free conversion factories pulls jobs from the most overloaded peer. This pull-based model keeps the cluster self-balancing:
- newly started peers naturally take their share of the load as soon as they join,
- slower peers pull fewer jobs, so they are never overwhelmed,
- aborted jobs and timeouts are propagated back to the remote peer,
- a peer stops stealing new jobs as soon as it begins a graceful shutdown.
To confirm the balancer is working, watch the carbone_reports_inflight{stage="conversion"} gauge on the Metrics page: a high, sustained conversion value on one node while others sit idle is exactly what it flattens.