Deploy on Azure
Run Elixium on Microsoft Azure using Azure Container Apps for containers, Azure Database for PostgreSQL for the database, and Azure Blob Storage for objects. This guide covers a production-ready deployment using managed Azure services.
Prerequisites
- Azure subscription with an active resource group
- Azure CLI configured (
az login) - Docker installed locally (for image pull/push)
- Elixium enterprise license key
Architecture Overview
| Component | Azure Service | Notes |
|---|---|---|
| Frontend + API | Azure Container Apps | Serverless containers, scales to zero |
| Database | Azure Database for PostgreSQL (Flexible Server) | Managed backups, HA optional |
| File Storage | Azure Blob Storage | S3-compatible via Azurite or gateway |
| Authentication | Azure Container Apps (Keycloak) | Backed by PostgreSQL |
| AI Inference | Gemini (default), OpenAI, Azure OpenAI, or Ollama (external GPU) | Cloud AI provider or self-hosted Ollama |
| Container Registry | Azure Container Registry (ACR) | Mirror images from GHCR |
Step 1: Create Resource Group & Container Registry
Set up the resource group and push Elixium images to Azure Container Registry:
# Create resource group az group create --name elixium-rg --location <region> # Create Azure Container Registry az acr create --resource-group elixium-rg \ --name elixiumacr --sku Basic # Log in to ACR az acr login --name elixiumacr # Pull from GHCR and push to ACR 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 Infrastructure
Azure Database for PostgreSQL
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
Azure Blob Storage
az storage account create \ --resource-group elixium-rg \ --name elixiumuploads \ --location <region> \ --sku Standard_LRS # Create container for uploads az storage container create \ --account-name elixiumuploads \ --name elixium-uploads \ --public-access blob # Get storage key for S3-compatible access az storage account keys list \ --resource-group elixium-rg \ --account-name elixiumuploads
Step 3: Create Container Apps Environment
Azure Container Apps provides a managed environment for running containers with built-in scaling, HTTPS ingress, and service discovery:
# Create Container Apps environment az containerapp env create \ --resource-group elixium-rg \ --name elixium-env \ --location <region> # Enable ACR access for the environment az containerapp env identity assign \ --resource-group elixium-rg \ --name elixium-env \ --system-assigned
Step 4: Deploy Container Apps
Keycloak
az containerapp create \
--resource-group elixium-rg \
--environment elixium-env \
--name keycloak \
--image quay.io/keycloak/keycloak:23.0 \
--target-port 8080 \
--ingress external \
--cpu 1.0 --memory 2.0Gi \
--min-replicas 1 --max-replicas 2 \
--command "start" "--import-realm" "--health-enabled=true" \
--env-vars \
KC_DB=postgres \
KC_DB_URL="jdbc:postgresql://elixium-db.postgres.database.azure.com:5432/elixium" \
KC_DB_USERNAME=elixium \
KC_DB_PASSWORD=<your-secure-password> \
KC_HOSTNAME_STRICT=false \
KC_HTTP_ENABLED=true \
KC_HEALTH_ENABLED=trueElixium 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 --max-replicas 4 \
--env-vars \
ELIXIUM_MODE=local \
NODE_ENV=production \
DATABASE_URL="postgresql://elixium:<password>@elixium-db.postgres.database.azure.com:5432/elixium?sslmode=require" \
KEYCLOAK_URL=https://<keycloak-app-url> \
KEYCLOAK_REALM=elixium \
KEYCLOAK_CLIENT_SECRET=<your-client-secret> \
AI_PROVIDER=gemini \
MINIO_ENDPOINT=elixiumuploads.blob.core.windows.net \
ELIXIUM_LICENSE_KEY=<your-license-key>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 --max-replicas 4 \
--env-vars \
ELIXIUM_MODE=local \
NODE_ENV=production \
NEXT_PUBLIC_ELIXIUM_MODE=local \
NEXT_PUBLIC_KEYCLOAK_URL=https://<keycloak-app-url>Step 5: Custom Domain & TLS
# Add custom domain to Container App az containerapp hostname add \ --resource-group elixium-rg \ --name elixium-app \ --hostname elixium.yourcompany.com # Bind a managed certificate (auto-renewing TLS) az containerapp hostname bind \ --resource-group elixium-rg \ --name elixium-app \ --hostname elixium.yourcompany.com \ --environment elixium-env \ --validation-method CNAME
Add the CNAME record shown in the output to your DNS provider. Azure Container Apps provides free managed TLS certificates that auto-renew.
Estimated Monthly Cost
| Service | Configuration | Est. Cost |
|---|---|---|
| Container Apps (3 apps) | App + API + Keycloak, min 1 replica | ~$80 |
| PostgreSQL Flexible Server | Standard_B1ms, 32GB storage | ~$50 |
| Blob Storage | Standard LRS, minimal usage | <$1 |
| AI Provider (optional GPU) | Gemini API or Ollama on NC-series VM | $0–$350 |
| Total (without GPU) | ~$160/mo | |
Budget Option: Single Azure VM (~$35/mo)
For small teams (under 10 users), you can run all Elixium services on a single Azure VM using the same Docker Compose setup from the self-hosted guide. This eliminates the cost of Container Apps, managed PostgreSQL, and other services.
Terraform via Command Center (Coming Soon)
Terraform modules for Azure (including Azure Government) are on the roadmap. Once available, you'll be able to download a pre-configured deployment bundle from your Elixium Command Center (Settings → Deployment → Download Bundle) — the same workflow available today for AWS. In the meantime, use the manual setup below.
Manual Setup
Launch an Azure VM and follow the Self-Hosted (Docker) guide:
# 1. Create resource group az group create --name elixium-rg --location <region> # 2. Launch the VM az vm create \ --resource-group elixium-rg \ --name elixium \ --image Ubuntu2204 \ --size Standard_B2s \ --admin-username azureuser \ --generate-ssh-keys \ --os-disk-size-gb 30 \ --public-ip-sku Standard # 3. Open ports az vm open-port --resource-group elixium-rg \ --name elixium --port 80,443,3000 # 4. SSH in and install Docker ssh azureuser@<public-ip> sudo apt-get update && sudo apt-get install -y docker.io docker-compose-v2 sudo systemctl enable --now docker # 5. Follow the Self-Hosted (Docker) guide from here
| Service | Configuration | Est. Cost |
|---|---|---|
| Azure VM | Standard_B2s (2 vCPU, 4GB RAM) | ~$30 |
| OS Disk | 30GB Standard SSD | ~$2 |
| Public IP | Standard static IP | ~$4 |
| Total | ~$36/mo | |
Trade-offs: No auto-scaling, no managed database backups (set up pg_dump cron), and a single point of failure. Great for getting started — you can migrate to the managed architecture above as your team grows.
Need help with your Azure deployment? Contact [email protected] or back to self-hosted docs.
