Deploy on Azure

Run Elixium on your own Azure infrastructure. Start with a single Linux VM via Terraform in minutes, then scale to managed services as your team grows.

Prerequisites

  • Azure subscription with a configured az login session
  • Terraform 1.5+ installed (brew install terraform or download)
  • Elixium enterprise license key (from your Command Center → Deployment tab)

Getting Started with Terraform

The fastest path to a running Elixium instance. Download a pre-configured Terraform bundle from your Command Center — no Azure CLI required beyond initial authentication.

# 1. Download your deployment bundle from the Command Center

Go to Command Center → Deployment → Docker Compose → Download Bundle

# 2. Extract and navigate to the Azure Terraform directory

$ unzip elixium-docker-compose-bundle-*.zip

$ cd terraform/deployments/azure/docker-compose

# 3. Add your SSH public key and GHCR credentials to terraform.tfvars

$ nano terraform.tfvars

ssh_public_key = "ssh-rsa AAAA..." # must be RSA (Azure does not support ed25519)

ghcr_user = "your-github-user"

ghcr_token = "your-ghcr-pat"

# 4. Deploy

$ terraform init

$ terraform plan

$ terraform apply

# 5. Validate (~5 minutes after apply)

$ ./scripts/validate-deployment.sh $(terraform output -raw public_ip)

What Terraform Creates

ResourceDetails
Resource GroupDedicated RG for all Elixium resources
VNet + SubnetIsolated network with public subnet
Network Security GroupSSH + HTTPS only (configurable deployer CIDR)
Linux VMStandard_B2ms (2 vCPU, 8GB) with Docker Compose via cloud-init
TLSAuto-generated via nginx on port 443

Supports FIPS 140-2 for Azure Government and FedRAMP environments. Passwords are auto-generated if not provided. Air-gapped mode disables egress.

Estimated Monthly Cost

ServiceConfigurationEst. Cost
Azure VMStandard_B2ms (2 vCPU, 8GB RAM)~$35
OS Disk100GB Standard SSD~$8
Public IPStandard static IP~$4
Total~$47/mo

Troubleshooting

SkuNotAvailable: VM size is not available in location

Azure free trial and new pay-as-you-go subscriptions have zero vCPU quota for most VM sizes. B-series burstable VMs (Standard_B2ms) also have frequent capacity constraints in US East regions.

Fix: Request a vCPU quota increase in the Azure Portal under Subscriptions → Usage + quotas, or try a different region (westus3, northcentralus, canadacentral tend to have better availability). You can also switch to Standard_D2s_v3 or Standard_D2as_v5 in your terraform.tfvars.

Azure requires RSA SSH keys

Azure VMs do not support ed25519 SSH keys. If you see an error about unsupported key types, generate an RSA key:

ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_azure

"Root object was present, but now absent"

This is a known bug in the azurerm Terraform provider (v3.x). Azure creates the resource but the provider loses track of it.

Fix: Run terraform apply again. Terraform will detect the existing resource and continue. If it says "already exists", import it: terraform import <resource_address> <azure_resource_id>

Production Architecture: Managed Services

For larger teams or high-availability requirements, deploy Elixium using managed Azure services. This architecture uses Container Apps, Azure Database for PostgreSQL, and Blob Storage — replacing the single-VM Docker Compose setup with auto-scaling and managed backups.

Requires Azure CLI

The managed services setup below uses az CLI commands. Install it with brew install azure-cli or from the Azure CLI docs. If you're just getting started, use the Terraform approach above instead.

Architecture Overview

ComponentAzure ServiceNotes
Frontend + APIAzure Container AppsServerless containers, scales to zero
DatabaseAzure Database for PostgreSQL (Flexible Server)Managed backups, HA optional
File StorageAzure Blob StorageS3-compatible via gateway
AuthenticationAzure Container Apps (Keycloak)Backed by PostgreSQL
AI InferenceGemini (default), OpenAI, Azure OpenAI, or OllamaCloud AI or self-hosted Ollama (external GPU)
Container RegistryAzure Container Registry (ACR)Mirror images from GHCR

Step 1: Create Resource Group & Container Registry

# Create resource group
az group create --name elixium-rg --location <region>

# Create ACR and mirror images from GHCR
az acr create --resource-group elixium-rg --name elixiumacr --sku Basic
az acr login --name elixiumacr

docker login ghcr.io
docker pull ghcr.io/indirecttek/elixium-app:latest
docker pull ghcr.io/indirecttek/elixium-api:latest

docker tag ghcr.io/indirecttek/elixium-app:latest elixiumacr.azurecr.io/elixium-app:latest
docker tag ghcr.io/indirecttek/elixium-api:latest elixiumacr.azurecr.io/elixium-api:latest
docker push elixiumacr.azurecr.io/elixium-app:latest
docker push elixiumacr.azurecr.io/elixium-api:latest

Step 2: Provision Database & Storage

# PostgreSQL Flexible Server
az postgres flexible-server create \
  --resource-group elixium-rg --name elixium-db \
  --location <region> --admin-user elixium \
  --admin-password <your-secure-password> \
  --sku-name Standard_B1ms --version 16 --storage-size 32

az postgres flexible-server db create \
  --resource-group elixium-rg --server-name elixium-db --database-name elixium

# Blob Storage
az storage account create --resource-group elixium-rg \
  --name elixiumuploads --location <region> --sku Standard_LRS

Step 3: Deploy Container Apps

# Create Container Apps environment
az containerapp env create --resource-group elixium-rg \
  --name elixium-env --location <region>

# Deploy Elixium API
az containerapp create --resource-group elixium-rg \
  --environment elixium-env --name elixium-api \
  --image elixiumacr.azurecr.io/elixium-api:latest \
  --registry-server elixiumacr.azurecr.io \
  --target-port 3001 --ingress external \
  --cpu 1.0 --memory 2.0Gi --min-replicas 1 \
  --env-vars ELIXIUM_MODE=local NODE_ENV=production \
    AI_PROVIDER=gemini ELIXIUM_LICENSE_KEY=<your-license-key>

# Deploy Elixium App (Frontend)
az containerapp create --resource-group elixium-rg \
  --environment elixium-env --name elixium-app \
  --image elixiumacr.azurecr.io/elixium-app:latest \
  --registry-server elixiumacr.azurecr.io \
  --target-port 3000 --ingress external \
  --cpu 0.5 --memory 1.0Gi --min-replicas 1

Step 4: Custom Domain & TLS

az containerapp hostname add --resource-group elixium-rg \
  --name elixium-app --hostname elixium.yourcompany.com

az containerapp hostname bind --resource-group elixium-rg \
  --name elixium-app --hostname elixium.yourcompany.com \
  --environment elixium-env --validation-method CNAME

Estimated Monthly Cost (Managed)

ServiceConfigurationEst. Cost
Container Apps (3 apps)App + API + Keycloak, min 1 replica~$80
PostgreSQL Flexible ServerStandard_B1ms, 32GB storage~$50
Blob StorageStandard LRS, minimal usage<$1
AI Provider (optional GPU)Gemini API or Ollama on NC-series VM$0–$350
Total (without GPU)~$160/mo

Need help with your Azure deployment? Contact [email protected] or back to self-hosted docs.