Self-hosted deployment

Deploy on Azure

Generate and manage your reports inside your own Azure environment using Container Apps

Introduction

Deploying Carbone in an Azure Container Apps environment is a very simple and effective way of implementing high-performance document generation while respecting your security and operation processes.

By default, the program runs with free Community features. To use Carbone Enterprise Edition, you need a Carbone license. Contact us to learn more, or request a free 30-day trial in our chat.

Deploy via Azure Marketplace

The fastest way to get Carbone running on Azure is our official listing on the Azure Marketplace: Carbone - Document generator. Click Get it now, sign in with your Azure account, and follow the guided deployment.

It deploys the same carbone/carbone-ee container image described on this page, so every environment variable covered in Configuration below — storage, Studio, authentication — applies the same way.

The listing is Bring Your Own License (BYOL): it costs nothing to deploy, but you still need a Carbone license to unlock Enterprise features.

The rest of this page walks through a manual setup with Azure Container Apps — useful if you want full control over storage, scaling, or authentication, or if you'd rather script the deployment (see the Terraform example below).

Quickstart

Create Azure storage for persistent data

1. Create Storage accounts for Carbone

Go to Storage accounts section in Azure portal and click on Create:

Storage creation step 1

Then set storage name, following carbonestorage, click on Review + create and Create again:

Storage creation step 2

2. Create Template and Render containers

When the Storage Account creation is finalized, you can create 2 containers.

Click on Create in Data storage / Containers section :

Storage creation step 3

Then, create 2 containers : templatesand renders.

Storage creation step 4

3. Get credentials

Finally, you need to get Storage Account Name and Account key from the Azure portal. Go to Security + Network / Access Key settings.

Storage creation step 5

Keep these two values for the next step.

Create Carbone service

Go to Container Apps in the Azure portal, and create a new Container App:

Service creation step 1

Create container carbone with following configuration.

Basic

Service creation step 2

Container

Service creation step 3

Service creation step 4

Ingress

For a simple test setup, enable full access and set port to 4000. For production, restrict ingress (limited/internal traffic) or enable Carbone authentication instead of leaving the API publicly reachable:

Service creation step 5

Enjoy Carbone

Your service is then available via the url of your Container App.

Configuration

Storage backends

As indicated in the quick start section, we recommend that you configure the Azure Blob Storage plugin to store rendering templates.

To do this, set the CARBONE_USE_AZURE_PLUGIN environment variable to true, then choose one of the following authentication methods (see the plugin documentation for the full reference).

System-assigned managed identity (recommended for Container Apps)

Enable a system-assigned managed identity on your Container App, grant it the Storage Blob Data Contributor role on the Storage Account, then set:

No storage key to manage or rotate.

User-assigned managed identity

Same as above, but using a user-assigned identity — add its client ID:

Shared key

Not recommended for production deployments on Container Apps — prefer a managed identity above.

Default Azure credentials

Set AZURE_USE_DEFAULT_AZURE_CREDENTIALS=true along with AZURE_STORAGE_ACCOUNT, then provide the additional environment variables required by DefaultAzureCredential — mainly useful outside Container Apps, for example for local development against a real Azure account.

Enable Studio

Just set CARBONE_STUDIO to true to enable Carbone Studio on your instance.

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.

Keep the private key content secure — it never leaves your machine, it is only used to generate JWT tokens. For the public key, store its content as a secret on your Container App (Secrets section), then reference that secret from the CARBONE_AUTHENTICATION_PUBLIC_KEY environment variable.

- Generate JWT token

Follow 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

Azure Container Apps scales natively — no clustering or peer configuration needed, since template and render storage is external (Blob Storage, see Storage backends above).

In the Scale section of your Container App, configure:

Infrastructure as Code

Carbone autoscaling deployment with secret storage

A complete Terraform deployment example is available.

Upgrade

Azure Container Apps is revision-based: updating the container image or configuration creates a new revision. By default (single revision mode), 100% of traffic shifts to the new revision automatically once it's healthy. If you enable multiple revision mode, you can split traffic between revisions for a canary rollout.

Because templates and renders live in Blob Storage rather than on the container's local disk, deploying a new revision is safe and stateless.

Troubleshooting

Container logs. Use the Log stream tab on your Container App, or query the Log Analytics workspace linked to your Container Apps environment, for application-level errors.

Revision stuck in Activating / Failed. Common causes:

403 / connection errors to Blob Storage. Re-check AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_KEY, and that the containers named in CONTAINER_TEMPLATES / CONTAINER_RENDERS exist (see Storage backends).