Self-hosted deployment
Deploy with Docker
Deploy Carbone on your server with Docker
Introduction
Carbone reference images are available on Docker Hub. You can choose between 3 variants:
slim: Minimal version of Carbone. This image does not include Libreoffice (no PDF generation possible).latest,full: Full version of Carbone including the latest version of LibreOfficelatest-fonts,full-fonts: Full version of Carbone including the latest version of LibreOffice. This version also includes all Google Fonts (royalty-free).
You can use Carbone Community features for free without a license.
To use Carbone Enterprise Edition on docker, you need a Carbone license. Talk to us to find out more.
Quickstart
Run a single container
To start your instance simply :
export CARBONE_LICENSE=`MY_CARBONE_LICENSE`
docker run -t -i --rm -p 4000:4000 -e CARBONE_LICENSE -e CARBONE_STUDIO=true carbone/carbone-ee
Run with Docker Compose
Example of docker-compose.yml to run a Carbone container, with the license stored as a Docker secret rather than an environment variable:
version: "3.9"
services:
carbone:
image: carbone-ee
ports:
- "4000:4000"
secrets:
- source: carbone-license
target: /app/config/prod.carbone-license
environment:
- CARBONE_STUDIO=true
volumes:
- ./template:/app/template
- ./render:/app/render
secrets:
carbone-license:
file: your_license.carbone-license
To start the stack:
docker-compose up
Configuration
All configuration options can be used by setting environment variables.
Storage backends
By default, persistent data is stored inside the container.
For production use, you need to configure a persistent storage space.
Bind-mounted volume. With a single Carbone instance, only the /app/template folder needs to be bound to a host folder. With multiple instances, you must also bind the /app/render folder.
# Start Carbone with /app/template bind on local folder
docker run -t -i --rm -p 4000:4000 -e CARBONE_LICENSE -e CARBONE_STUDIO=true --volume ./template:/app/template carbone/carbone-ee
S3 or Azure Blob Storage. Two plugins are preinstalled in docker images:
- carbone-ee-plugin-s3 : Storage of templates and/or renders on an S3-compatible bucket
- carbone-ee-plugin-azure-storage-blob : Storage of templates and/or renders on an Azure Blob Storage
Here are the environment variables for configuring these plugins:
CARBONE_USE_S3_PLUGIN: set totrueto enable S3 plugin. Default :trueCARBONE_USE_AZURE_PLUGIN: set totrueto enable Azure Blob Storage plugin, and disable S3 plugin. Default :false
S3 Configuration
AWS_ACCESS_KEY_ID: Access Key IDAWS_SECRET_ACCESS_KEY: Secret KeyAWS_ENDPOINT_URL: s3.amazonaws.com for AWS, storage.googleapis.com for GCP StorageAWS_REGION: storage regionBUCKET_RENDERS: "BUCKET NAME to store your generated documents"BUCKET_TEMPLATES: "BUCKET NAME to store your templates"
Azure Blob Storage Configuration
AZURE_STORAGE_ACCOUNT: Storage Account NameAZURE_STORAGE_KEY: Storage Account KeyCONTAINER_TEMPLATES: Templates Storage NameCONTAINER_RENDERS: Renders Storage Name
Enable Studio
Set the CARBONE_STUDIO environment variable to true to enable Carbone Studio (already shown in the quickstart above).
Authentication
To enable API authentication, you need to follow these steps :
- Set CARBONE_AUTHENTICATION to true
- Generate private/public Carbone Key
The key generation tool is included in the docker image from Carbone version 5 onwards.
docker run -it --platform "linux/amd64" carbone/carbone-ee:slim-5.0.0-beta.0 generate-keys
The two keys will be generated and displayed in the console. Create the files key.pem (with private key) and key.pub (with public key).
- Generate JWT token
Follow the interactive shell:
docker run -it --platform "linux/amd64" carbone/carbone-ee:slim-5.0.0-beta.0 generate-token
## Paste in terminal content of key.pem
A JWT token is then displayed in the console. You can then use it in your API calls.
Scaling and availability
To run several Carbone instances behind a reverse proxy, scale the carbone service in docker-compose.yml and share storage across replicas (a bind-mounted volume works for a single host, S3 or Azure Blob Storage for multi-host setups).
Example of docker-compose.yml with a high-availability setup, authentication and reverse proxy :
version: "3.9"
services:
carbone:
image: "carbone/carbone-ee:full"
deploy:
replicas: 3
ports:
- "4000"
secrets:
- source: carbone-license
target: /app/config/license.carbone-license
- source: carbone-publickey
target: /app/config/key.pub
environment:
- CARBONE_STUDIO=true
- CARBONE_AUTHENTICATION=true
- CARBONE_STUDIO_USER=toto:Passw0rd
volumes:
- ./template:/app/template
- ./render:/app/render
nginx:
image: nginx:latest
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- carbone
ports:
- "4000:4000"
secrets:
carbone-license:
file: license.carbone-license
carbone-publickey:
file: key.pub
Content of nginx.conf :
user nginx;
events {
worker_connections 1000;
}
http {
server {
listen 4000;
location / {
proxy_pass http://carbone:4000;
}
client_max_body_size 20M;
}
}Replicas run independently by default (no metadata replication). If you need template management or the job balancer across containers, enable clustering with CARBONE_TEMPLATE_MANAGEMENT, CARBONE_PEER_PORT and CARBONE_PEER_ENDPOINTS — see HA and Scaling.
Infrastructure as Code
Ready-to-use docker-compose examples are available in the carbone-ee-docker repository:
| Scenario | Folder |
|---|---|
| Single instance | simple |
| Multiple instances behind a reverse proxy | multiInstance |
| HTTPS with Let's Encrypt / certbot | https |
| Reverse proxy with authentication | proxy-auth |
Upgrade
To upgrade, pull the new image tag and recreate the container(s):
docker pull carbone/carbone-ee:full
docker compose up -d
This is safe as long as /app/template (and /app/render, for multiple instances) is on a bind-mounted volume or external storage (S3, Azure Blob Storage) rather than inside the container, so template data survives the recreation.
Troubleshooting
Container logs
docker logs <container_name>
Permission denied on the template/render volume. The Carbone process inside the container runs as a non-root user. If you bind-mount a host folder, make sure it is writable by that user, for example:
mkdir -p ./template ./render
chmod 777 ./template ./render
Port already allocated. Another process (or a previous Carbone container) is already bound to the host port. Stop it, or map Carbone to a different host port with -p <host_port>:4000.
401 on Studio or the API after enabling authentication. Double-check that CARBONE_STUDIO_USER (Studio basic auth) or the JWT Authorization: Bearer header (API authentication) matches what you configured — the two are independent.