Carbone
The Carbone server that renders every document: running it with Compose, connecting it in Settings, Carbone Cloud, and the Community and Enterprise editions.
Spooldoc renders every document with Carbone: HTML and PDF from an HTML template, DOCX and PDF from a Word template, XLSX and PDF from an Excel template. Carbone runs as your own service, or you use Carbone Cloud. Spooldoc only calls it over HTTP; it never bundles or hosts Carbone. Without a working Carbone server there is nothing to render, so the job builder and the setup checklist on Home say what to do.
With Compose
The Compose file runs Carbone next to Spooldoc as the
carbone service: the carbone/carbone-ee image on a pinned
full-...-fonts tag, which has the converters and a wide set of fonts.
Its port 4000 is reachable only inside the Compose network, at
http://carbone:4000, which is Spooldoc's default.
Carbone runs with CARBONE_AUTHENTICATION=true: it accepts a request only
when it carries a token signed with Spooldoc's own key. Spooldoc makes the
key pair the first time it starts and keeps the private key encrypted in
its database. To give Carbone the public key:
-
Open Settings. Under Rendering, copy Spooldoc's public key. It is one line, with its newlines written as
\n. -
Put it in
.envnext tocompose.yaml:CARBONE_AUTHENTICATION_PUBLIC_KEY=-----BEGIN PUBLIC KEY-----\nMIGbMBAGByqGSM49...\n-----END PUBLIC KEY-----Keep the
\nas written. A real line break makes Carbone exit when it starts. -
Restart Carbone with
docker compose up -d carbone. -
Click Check again under Rendering.
Each token is valid for five minutes. When SPOOLDOC_SECRET_KEY changes,
the private key can't be read any more: Spooldoc makes a new pair, and
Carbone needs the new public key.
Settings
Settings has a Rendering section, the only place the connection is set:
| Setting | What it is |
|---|---|
| Carbone on-prem | The URL of your Carbone server, http://carbone:4000 by default. The Spooldoc server calls it, so it must be reachable from there. |
| Carbone Cloud | Your own API key from your Carbone account, stored encrypted with SPOOLDOC_SECRET_KEY and never shown again. |
Rendering shows whether the connection works, the Carbone version and the edition. Spooldoc checks the connection when it starts, after each change to the section, every ten minutes and when you click Check again. A render that can't reach Carbone, or that Carbone refuses, shows at once.
With Carbone Cloud, the data of each document goes to Carbone's servers to be rendered, and each document counts toward your Carbone plan. See Security.
Community and Enterprise
Carbone's Community Edition is free to run on-prem and renders everything
the starter template and the template docs use: tags,
loops, conditions, formatN, formatD and the other formatters, :set,
PDF headers and footers, and Word and Excel templates.
Carbone runs under its own license.
A license for Carbone Enterprise adds, among others:
| Feature | Example |
|---|---|
| Aggregators | {d.pg.lines[].amount:aggSum:formatN(2)} |
| Dropping an element | {d.pg.lines[i].amount:ifEM:drop(row)} |
| HTML from the data | {d.pg.note:html} |
| Barcodes and QR codes | <img src="{d.pg.invoiceNo:barcode(qrcode)}"> |
| Colors from the data | {d.pg.status:color(row, background)} |
| Charts | <img src="{d.pg.chart:chart}"> |
| Pictures from the data in a Word template | A logo per customer. On Community, Carbone keeps the template's picture without an error. |
| Aggregators and links from the data in an Excel template | {d.pgs[].lines[].amount:aggSum} as a number cell. On Community, total with a formula instead (see Excel templates). |
Carbone Cloud has the Enterprise features.
/status does not say which edition a server runs, so Spooldoc renders a
one-line probe with :aggSum. Enterprise renders it; Community refuses it
with "disabled in the Community Edition". Spooldoc keeps the answer, shows
it in Settings, and tells the agent not to use
Enterprise features on Community. Carbone Cloud is not probed, since each
probe there counts as a document. A template that uses an Enterprise
feature on Community fails with a message that names the feature.
To run Enterprise on-prem, put the license in CARBONE_LICENSE in .env
and restart Carbone. A license Carbone does not accept, and one that
expired, look exactly like no license: Carbone starts as Community and
only its startup log says why. So when Settings shows Community Edition
and you have a license, check Carbone's log with
docker compose logs carbone. Don't paste that log into an issue: with a
license, it prints the licensee's name and email.
Converters
Carbone makes a PDF with one of its converters. Spooldoc picks it:
| Template | Converter |
|---|---|
| HTML | Chromium |
| Word | Carbone's own converter (ICE), the fastest |
| Word with cross-references (PAGEREF or REF fields) | LibreOffice, which works them out |
| Excel | LibreOffice, which follows each sheet's page setup and prints every sheet |
The full images have all three. Carbone's API has no page size or fit
to page option for a spreadsheet, so an Excel template's PDF is laid out
by the sheet's own page setup (see The PDF).
A DOCX file is the Word template as Carbone filled it in, with no
converter. Spooldoc asks for it with hardRefresh off: otherwise Carbone
Enterprise passes a file with page fields through LibreOffice, which
rewrites its layout. Word fills in the page fields when it opens the
file.
An XLSX file is passed through LibreOffice (hardRefresh on) when the
template has formulas or numbers written with :formatN. LibreOffice
works out the formulas and stores their values, so a preview or a mail
viewer shows the totals, and it writes an empty number as an empty cell.
It takes about 40 ms more. A template without either gets the file as
Carbone filled it in.
When Carbone stops working
A watched queue does not lose files while Carbone is down or refuses Spooldoc. The watcher starts no runs, and new spooled files wait on the queue. Each watching job says "New spooled files wait until Carbone works again", with the reason, in its trigger step and under Needs attention on Home. While files wait, Spooldoc checks Carbone again at most once a minute. Once it works, the files run, oldest first. See Watching a queue.
Only the render that first finds Carbone down fails. Retry it from the Job log.
Errors
| Message | What to do |
|---|---|
| Could not reach Carbone at ... | Start the Carbone service, or fix the URL under Rendering. |
| Carbone refused Spooldoc's token ... | Set CARBONE_AUTHENTICATION_PUBLIC_KEY to the public key under Rendering and restart Carbone. |
| Carbone Cloud refused the API key ... | Check the key under Rendering. |
| Carbone at ... did not answer within 30 s | The server is down or overloaded. A render waits 30 seconds at most. |
| The template uses :aggSum, which needs Carbone Enterprise ... | Remove the feature, or use a server with an Enterprise license. |
Template errors, such as a loop without its [i+1] row, are on the
Templates page. Carbone's own
text is kept under Details for support.