High Availability on Azure¶
This page shows how to run a redundant CxReports setup on Azure. Read High Availability & Redundancy first for the general concepts and settings — this page only covers the Azure-specific choices.
Disclaimer
This is a self-managed deployment and doesn't cover every production security/networking detail. If you'd prefer high availability, scaling, backups, and monitoring handled for you, consider one of our managed cloud packages.
Which Azure services to use¶
| CxReports needs | Azure service |
|---|---|
| The app, running as 2+ instances | Azure Container Apps (simplest) or Azure Kubernetes Service (AKS) for more control. Azure App Service (scale-out, custom container) also works. |
| A shared PostgreSQL database | Azure Database for PostgreSQL – Flexible Server, with high availability (zone-redundant) enabled. |
| A NATS server | Run NATS yourself (a 3-node cluster — the official NATS Helm chart on AKS is the easiest), or use Synadia Cloud (managed NATS). There is no built-in Azure NATS service. |
| A load balancer | The built-in ingress of Container Apps / AKS / App Service. |
No Azure Cache for Redis is needed.
Configuration¶
Set the HA settings as Container App secrets, Kubernetes secrets, or App Service application settings — the same on every instance:
| Setting | Value |
|---|---|
HighAvailability__Enabled |
true |
Nats__Enabled |
true |
Nats__Url |
nats://<your-nats-service>:4222 |
ConnectionStrings__Database |
Host=<server>.postgres.database.azure.com;Port=5432;Database=cxreports;Username=<user>;Password=<password>;SSL Mode=Require |
Encryption__Key, Encryption__Vector |
your keys |
RootUser__Email, RootUser__Password |
your root credentials |
Azure-specific tips¶
- Connect to PostgreSQL directly, not through the pooler. Flexible Server offers a built-in PgBouncer connection pooler. CxReports uses session-level database locks for coordinating instances, which aren't compatible with the pooler's transaction mode — so point the connection string at the direct port (5432), not the pooler port (6432).
- Turn off session affinity / ARR affinity on the ingress (Application Gateway, App Service). CxReports doesn't need it, and it can interfere with failover.
- Allow WebSockets on the ingress (used for live report progress) — Container Apps and Application Gateway support this.
- Don't set the app's public URL as its internal URL — leave the instance URL at its default so PDF rendering keeps working.
- Pick a database tier with enough connections for all instances combined.
- Shared fonts: if you upload custom fonts, mount Azure Files at the font folder so all instances share them.
- Monitoring: Azure Monitor / Application Insights work well; each log line is tagged with its instance, so you can tell which instance produced it.
Before going live¶
- Run NATS clustered and PostgreSQL in HA mode — both are needed for true redundancy.
- Set up backups (see Database Backup) and basic alerting.
- Do a test run at production-like load before switching
HighAvailability__Enabledon in production.