Skip to main content

Install Avon AI on Azure Platform

Deployment Type: Single Docker Container on Azure VM Version: 1.6.6


Overview

Avon AI is deployed as a single Docker container that bundles all required services internally (MongoDB, Redis, ChromaDB, Nginx, and all Avon microservices). This guide walks through deploying Avon version 1.6.6 on an Azure Virtual Machine (the Azure equivalent of an AWS EC2 instance).

The container exposes a single port to the outside world. All inter-service communication happens on localhost inside the container.


Prerequisites Checklist

Before starting, make sure you have the following ready:

  • Azure VM provisioned with a supported Linux distribution and Docker installed
  • Azure OpenAI resource created with three model deployments (gpt-4o, gpt-4o-mini, and text-embedding-3-small)
  • Avon AI Docker image file (version 1.6.6) provided by the Avon team (loaded via docker load)
  • Domain / subdomain pointing to the Azure VM's public IP (e.g., avon.your-company.com)
  • SSL certificate and private key for the configured domain
  • Microsoft Entra (Azure AD) App Registration for SSO
  • Azure Blob Storage container for conversation ingestion
  • Network Security Group (NSG) rules configured to allow inbound traffic on port 443

Resource Requirements

The following table provides sizing guidance based on the expected number of users:

EnvironmentCPUMemoryStorage (Disk)
Small team (< 20 users)2 cores4 GiB25 GiB
Production (20-100 users)4 cores8 GiB50 GiB
Enterprise (100+ users)4 cores16 GiB100 GiB

Recommended Azure VM sizes:

TierAzure VM SizevCPUsMemory
SmallStandard_D2s_v528 GiB
ProductionStandard_D4s_v5416 GiB
EnterpriseStandard_D4s_v5 or D8s_v54-816-32 GiB
note

Storage refers to the persistent data volume, not the OS disk. Attach a separate Azure Managed Disk for the /data volume (see next section).


Data Volume (/data)

Avon uses a single persistent volume mounted at /data inside the container. This volume stores:

Path Inside ContainerPurpose
/data/dbMongoDB database files (conversations, configurations, users, etc.)
/data/chromadbChromaDB vector database (knowledge base embeddings)
/data/nginx/Generated SSL certificate files (written at container startup)

How to Configure

  1. Create an Azure Managed Disk (or use a local directory on the VM):

    • Recommended size: 50 GiB minimum for production, expandable as conversation volume grows.
    • Use Premium SSD (Premium_LRS) for best performance.
  2. Mount the disk on the Azure VM (e.g., at /mnt/avon-data):

# Example: format and mount a new disk
sudo mkfs.ext4 /dev/sdc
sudo mkdir -p /mnt/avon-data
sudo mount /dev/sdc /mnt/avon-data
  1. Pass it to Docker using the -v flag:
-v /mnt/avon-data:/data

Alternatively, use a Docker named volume:

docker volume create avon-data
# Then use: -v avon-data:/data
warning

Back up the /data volume regularly. It contains all your conversations, configurations, and knowledge base data.


Domain and Networking

Domain Configuration

Configure a domain or subdomain that points to the Azure VM's public IP address:

avon.your-company.com  →  A record  →  <Azure VM Public IP>

This domain will be used:

  • As the URL users access to use Avon
  • In the SSO redirect URI (https://avon.your-company.com/callback)
  • In the SSL certificate (must match the domain)

Ports

PortProtocolDirectionPurpose
443HTTPSInboundPrimary access port (when SSL is configured)
5173HTTPInboundFallback port (only if no SSL certificate is provided)

For production, only port 443 needs to be open.

All internal services run inside the container on localhost and do NOT require any external port exposure:

Internal ServiceInternal PortNotes
MongoDB27017Database - internal only
Redis6379Cache - internal only
BFF Service8000Backend API - proxied via Nginx
Registry Service8001Internal only
Database Service8002Internal only
Validation Job8003Internal only
KB Service8004Internal only
Ingestion Service8005Internal only
Test Runner Service8006Internal only
ChromaDB8070Vector DB - internal only

Azure NSG Rule

In your Azure Network Security Group, add an inbound rule:

PriorityNamePortProtocolSourceAction
100AllowHTTPS443TCPAny (or your IP range)Allow

Model Deployments (Azure OpenAI)

Step 1: Create Azure OpenAI Deployments

In the Azure OpenAI Studio, create three model deployments:

Deployment Name (example)ModelPurpose
gpt-4ogpt-4oComplex analysis, tier-1 tasks (topic extraction, alert summaries)
gpt-4o-minigpt-4o-miniDefault model for general tasks (validators, standard operations)
text-embedding-3-smalltext-embedding-3-smallKnowledge base embeddings
tip

The deployment name is what you choose in Azure OpenAI Studio. The examples above use the model name as the deployment name — this is the recommended convention and avoids extra configuration.

Step 2: Azure OpenAI Connection Variables

All three deployments share the same Azure OpenAI resource credentials:

AZURE_API_KEY="<your-azure-openai-api-key>"
AZURE_API_BASE="<your-azure-openai-endpoint>" # e.g. "https://your-company-openai.openai.azure.com"
AZURE_API_VERSION="2024-08-01-preview"

You can find these values in the Azure Portal under your Azure OpenAI resource > Keys and Endpoint.

Step 3: Chat Model Configuration Variables

# Default model - used for most operations
DEFAULT_MODEL="azure/gpt-4o-mini"

# Tier 1 - complex/expensive tasks
GENERAL_TIER_1_MODEL="azure/gpt-4o"

# Optional: explicit tier 2 and 3 (fall back to DEFAULT_MODEL if not set)
# GENERAL_TIER_2_MODEL="azure/<your-deployment-name>"
# GENERAL_TIER_3_MODEL="azure/<your-deployment-name>"

Step 4: Embedding Model Configuration

When AZURE_API_KEY is set, Avon automatically registers an Azure OpenAI embedding connection in the database at startup (named "Default Azure OpenAI"). No additional env vars are needed — the API key is resolved automatically at call time.

When creating a Knowledge Base in the Avon UI, select the "Default Azure OpenAI" connection and enter your text-embedding-3-small deployment name as the model.

Step 5: Azure Content Filtering

Azure OpenAI applies content filters to every request by default, evaluating prompts and responses for hate, sexual content, self-harm, and violence at severity thresholds of low, medium, or high.

caution

Conversations about sensitive business topics (account disputes, financial distress, etc.) can be misclassified by Azure's violence or self-harm filters, causing requests to be rejected with content_filter errors.

Content filtering is configured per deployment in Azure AI Studio — it is not a setting inside Avon.

To adjust filters:

  1. Go to Azure AI Studio → your resource → Deployments
  2. Select the deployment → EditContent filters tab
  3. Raise any category threshold to High or turn it off
OptionHowWhen to use
Raise threshold to "High"Edit deployment → set each filter to HighQuickest fix; still blocks clearly harmful content
Custom filter policyAzure AI Studio → Content filters → New policy → assign to deploymentPer-category control
Modified content filteringRequest via Azure supportFull removal for regulated industries

Additional Model Variables (Optional)

# TOPIC_DEFAULT_MODEL="azure/<your-deployment-name>"             # Topic extraction
# REGISTRY_TIER_1_MODEL="azure/<your-deployment-name>" # Complex validators
# REGISTRY_TIER_2_MODEL="azure/<your-deployment-name>" # Standard validators
# ALERTS_SUMMARY_DEFAULT_MODEL="azure/<your-deployment-name>" # Alert summaries

Authentication and Service Keys

Avon uses internal service-to-service authentication keys. Each key must be a unique, randomly generated hex string.

Generate Keys

openssl rand -hex 32

Required Keys

SECRET_KEY=<generate-64-char-hex>
SUPER_ADMIN_API_KEY=<generate-64-char-hex>
TEST_RUNNER_SERVICE_KEY=<generate-64-char-hex>
ENTERPRISE_AI_AGENTS_SERVICE_KEY=<generate-64-char-hex>
REGISTRY_SERVICE_KEY=<generate-64-char-hex>
VALIDATION_JOB_SERVICE_KEY=<generate-64-char-hex>
INGESTION_SERVICE_KEY=<generate-64-char-hex>
REPORTS_SERVICE_KEY=<generate-64-char-hex>

Quick Generate All Keys

echo "SECRET_KEY=$(openssl rand -hex 32)"
echo "SUPER_ADMIN_API_KEY=$(openssl rand -hex 32)"
echo "TEST_RUNNER_SERVICE_KEY=$(openssl rand -hex 32)"
echo "ENTERPRISE_AI_AGENTS_SERVICE_KEY=$(openssl rand -hex 32)"
echo "REGISTRY_SERVICE_KEY=$(openssl rand -hex 32)"
echo "VALIDATION_JOB_SERVICE_KEY=$(openssl rand -hex 32)"
echo "INGESTION_SERVICE_KEY=$(openssl rand -hex 32)"
echo "REPORTS_SERVICE_KEY=$(openssl rand -hex 32)"
danger

Generate each key separately. Do not reuse the same value for multiple keys. Store them securely (e.g., in Azure Key Vault).


SSO Configuration (Microsoft Entra / Azure AD)

Step 1: Register an Application

  1. Go to the Azure Portal > Microsoft Entra ID > App registrations > New registration
  2. Configure:
    • Name: Avon AI
    • Supported account types: Accounts in this organizational directory only (single tenant)
    • Redirect URI: Platform Web, URI https://avon.your-company.com/callback
  3. Note the Application (client) IDSSO_CLIENT_ID and Directory (tenant) ID
  4. Go to Certificates & secrets > New client secretSSO_CLIENT_SECRET
warning

The application must be registered as a Web application (confidential client), not as a Single-Page Application (SPA).

Step 2: Environment Variables

SSO_PROVIDER="entra"
SSO_ISSUER="https://login.microsoftonline.com/<your-tenant-id>/v2.0"
SSO_CLIENT_ID="<your-application-client-id>"
SSO_CLIENT_SECRET="<your-client-secret>"

SSL / TLS Certificates

HTTPS Certificate (Required for Production)

HTTPS_CERTIFICATE="-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgI...
-----END CERTIFICATE-----"

HTTPS_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhki...
-----END PRIVATE KEY-----"
note

If HTTPS_CERTIFICATE is not set, the application defaults to HTTP on port 5173.

Internal CA Certificate (Optional)

If your Azure OpenAI endpoint uses a custom/internal CA:

SSL_CERT_FILE_CONTENTS="-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgI...
-----END CERTIFICATE-----"

Passing Certificates in Docker Run

-e HTTPS_CERTIFICATE="$(cat /path/to/cert.pem)" \
-e HTTPS_PRIVATE_KEY="$(cat /path/to/key.pem)" \

Conversation Ingestion (Azure Blob Storage)

Avon reads conversation files from an Azure Blob Storage container for automated ingestion.

How it works:

  • Avon connects using an az:// URL scheme
  • Files are discovered, ingested, and validated automatically on a schedule
  • Credentials: account key (recommended for Docker/VM) or Managed Identity (if key not set)

Step 1: Azure Blob Storage Setup

  1. In the Azure Portal, go to your Storage Account
  2. Create (or identify) the container where conversation files will be placed
  3. Note your Storage account name, account key (under Security + networking > Access keys), and container name

Step 2: Environment Variables

AZURE_STORAGE_ACCOUNT_NAME="<your-storage-account-name>"

# Required for Docker environments; omit to use Managed Identity
AZURE_STORAGE_ACCOUNT_KEY="<your-storage-account-key>"

# Use az:// prefix for Azure Blob Storage
S3_INGESTION_BUCKET="az://<your-container-name>"

Example:

AZURE_STORAGE_ACCOUNT_NAME="mycompanystorage"
AZURE_STORAGE_ACCOUNT_KEY="xxxxxx...=="
S3_INGESTION_BUCKET="az://conversations"
note

The S3_INGESTION_BUCKET variable name is kept for backward compatibility but fully supports Azure Blob Storage via the az:// prefix.

Authentication Options

ScenarioConfiguration
Docker / VM with account keySet both AZURE_STORAGE_ACCOUNT_NAME and AZURE_STORAGE_ACCOUNT_KEY
Azure VM with Managed IdentitySet only AZURE_STORAGE_ACCOUNT_NAME; omit AZURE_STORAGE_ACCOUNT_KEY

Additional Configuration

Environment and Logging

ENVIRONMENT="prod"    # Options: development, staging, prod
LOG_LEVEL="INFO" # Options: DEBUG, INFO, WARNING, ERROR

Validation Job Tuning

MAX_CONCURRENT_VALIDATIONS=1
MAX_CONCURRENT_VALIDATORS_PER_CONVERSATION=3
SCHEDULE_INTERVAL_HOURS=1.0
VALIDATION_DELAY_MINUTES=30

Reports and LLM

REPORT_JOB_TIMEOUT_SECONDS=7200
MAX_CONVERSATIONS_PER_REPORT=25000
LLM_TIMEOUT=120

How to Run

Step 1: Load the Docker Image

docker load < avon-ai-1.6.6.tar
docker images | grep avon-ai

Step 2: Future Updates

To update to a newer version, the Avon team will provide a new image file. Pull the latest deployment scripts first:

git pull origin main

Then repeat the docker load step with the new image.

Step 3: Prepare avon.env

# ============================================================================
# ENVIRONMENT
# ============================================================================
ENVIRONMENT=prod
LOG_LEVEL=INFO

# ============================================================================
# AZURE OPENAI
# ============================================================================
AZURE_API_KEY=<your-azure-openai-api-key>
AZURE_API_BASE=https://<your-resource-name>.openai.azure.com
AZURE_API_VERSION=2024-08-01-preview

# ============================================================================
# MODEL CONFIGURATION
# ============================================================================
DEFAULT_MODEL=azure/gpt-4o-mini
GENERAL_TIER_1_MODEL=azure/gpt-4o

# ============================================================================
# SERVICE KEYS (generate each with: openssl rand -hex 32)
# ============================================================================
SECRET_KEY=<generated-hex>
SUPER_ADMIN_API_KEY=<generated-hex>
TEST_RUNNER_SERVICE_KEY=<generated-hex>
ENTERPRISE_AI_AGENTS_SERVICE_KEY=<generated-hex>
REGISTRY_SERVICE_KEY=<generated-hex>
VALIDATION_JOB_SERVICE_KEY=<generated-hex>
INGESTION_SERVICE_KEY=<generated-hex>
REPORTS_SERVICE_KEY=<generated-hex>

# ============================================================================
# SSO (Microsoft Entra / Azure AD)
# ============================================================================
SSO_PROVIDER=entra
SSO_ISSUER=https://login.microsoftonline.com/<your-tenant-id>/v2.0
SSO_CLIENT_ID=<your-application-client-id>
SSO_CLIENT_SECRET=<your-client-secret>

# ============================================================================
# SSL CERTIFICATES (pass via -e flag in docker run, not here)
# ============================================================================
# HTTPS_CERTIFICATE=<cert-content>
# HTTPS_PRIVATE_KEY=<key-content>

# ============================================================================
# CONVERSATION INGESTION (Azure Blob Storage)
# ============================================================================
AZURE_STORAGE_ACCOUNT_NAME=<your-storage-account-name>
AZURE_STORAGE_ACCOUNT_KEY=<your-storage-account-key>
S3_INGESTION_BUCKET=az://<your-container-name>

# ============================================================================
# OPTIONAL TUNING
# ============================================================================
LLM_TIMEOUT=120
MAX_CONCURRENT_VALIDATORS_PER_CONVERSATION=3
REPORT_JOB_TIMEOUT_SECONDS=7200
MAX_CONVERSATIONS_PER_REPORT=25000

Step 4: Run the Container

docker run -d \
--name avon-ai \
--restart unless-stopped \
-p 443:443 \
-v /mnt/avon-data:/data \
--env-file avon.env \
-e HTTPS_CERTIFICATE="$(cat /path/to/cert.pem)" \
-e HTTPS_PRIVATE_KEY="$(cat /path/to/key.pem)" \
avon-ai:1.6.6
FlagPurpose
-dRun in detached (background) mode
--restart unless-stoppedAuto-restart on crash or VM reboot
-p 443:443Expose HTTPS port
-v /mnt/avon-data:/dataMount persistent storage
--env-file avon.envLoad environment variables from file
-e HTTPS_CERTIFICATE=...Pass certificate content (multi-line values)
note

SSL certificate and private key are passed as -e flags separately because --env-file does not handle multi-line values well.

Useful Commands

docker logs -f avon-ai          # View logs
docker stop avon-ai # Stop
docker start avon-ai # Start
docker restart avon-ai # Restart
docker exec -it avon-ai /bin/bash # Shell into container
docker rm avon-ai # Remove (data persists in volume)

Health Check and Verification

  1. Check container status:

    docker ps | grep avon-ai
  2. Check health endpoint:

    curl -k https://avon.your-company.com/

    You should receive an HTML response (the Avon UI).

  3. Check logs for errors:

    docker logs avon-ai 2>&1 | grep -i error
  4. Verify SSO: Navigate to https://avon.your-company.com in a browser — you should be redirected to the Microsoft login page.


Quick Reference: All Environment Variables

VariableRequiredDescription
ENVIRONMENTYesSet to prod
AZURE_API_KEYYesAzure OpenAI API key
AZURE_API_BASEYesAzure OpenAI endpoint URL
AZURE_API_VERSIONYesAzure OpenAI API version
DEFAULT_MODELYesDefault model: azure/gpt-4o-mini
GENERAL_TIER_1_MODELRecommendedTier 1 model: azure/gpt-4o
SECRET_KEYYesJWT signing key (64-char hex)
SUPER_ADMIN_API_KEYYesSuper admin API key (64-char hex)
TEST_RUNNER_SERVICE_KEYYesService key (64-char hex)
ENTERPRISE_AI_AGENTS_SERVICE_KEYYesService key (64-char hex)
REGISTRY_SERVICE_KEYYesService key (64-char hex)
VALIDATION_JOB_SERVICE_KEYYesService key (64-char hex)
INGESTION_SERVICE_KEYYesService key (64-char hex)
REPORTS_SERVICE_KEYYesService key (64-char hex)
SSO_PROVIDERYesSet to entra
SSO_ISSUERYesEntra issuer URL
SSO_CLIENT_IDYesEntra App client ID
SSO_CLIENT_SECRETYesEntra App client secret
HTTPS_CERTIFICATEYes (prod)PEM certificate content
HTTPS_PRIVATE_KEYYes (prod)PEM private key content
SSL_CERT_FILE_CONTENTSOptionalInternal CA bundle
AZURE_STORAGE_ACCOUNT_NAMEYesAzure Blob Storage account name
AZURE_STORAGE_ACCOUNT_KEYYes (Docker)Azure Blob Storage account key
S3_INGESTION_BUCKETYesSet to az://<container-name>
LLM_TIMEOUTOptionalLLM call timeout (default: 60s)
MAX_CONCURRENT_VALIDATORS_PER_CONVERSATIONOptionalParallel validators (default: 3)
LOG_LEVELOptionalLog level (default: INFO)