See Agility CMS in action. Watch a product demo
Deploy to Azure
This guide covers deploying your Agility CMS .NET application to Azure App Service, including one-click deployment, manual deployment, and CI/CD setup.
One-Click Deployment
The fastest way to deploy is using our Azure Resource Manager (ARM) templates.
Deploy Blazor Starter
Deploy MVC Starter
Deployment Parameters
| Parameter | Required | Default | Description |
|---|---|---|---|
webAppName | Yes | - | Globally unique name (becomes yourname.azurewebsites.net) |
instanceGuid | Yes | - | Agility CMS Instance GUID |
securityKey | Yes | - | Security key for preview mode |
fetchAPIKey | Yes | - | Live content API key |
previewAPIKey | Yes | - | Preview content API key |
locales | No | en-us | Comma-separated locale codes |
channelName | No | website | Agility sitemap channel |
sku | No | B1 | App Service Plan SKU |
SKU Requirements
| SKU | WebSockets | AlwaysOn | Recommended For |
|---|---|---|---|
| F1 (Free) | No | No | Not supported |
| D1 (Shared) | No | No | Not supported |
| B1 | Yes | Yes | Development/Testing |
| S1 | Yes | Yes | Production |
| P1V2+ | Yes | Yes | High-traffic production |
Important: The Blazor starter requires WebSockets for Interactive Server components. Choose B1 or higher.
What Gets Deployed
The ARM template creates:
- Linux App Service running .NET 10
- App Service Plan with your chosen SKU
- WebSockets enabled (required for Blazor Interactive Server)
- AlwaysOn enabled (keeps the app warm)
- HTTP/2 enabled (better performance)
- TLS 1.2 minimum (security)
- Git deployment from the repository
Manual Deployment
Using Visual Studio Code
-
Install Extensions
- Azure App Service extension
- Azure Resources extension
-
Build for Release
dotnet publish -c Release -o ./publish -
Deploy
- Right-click the
publishfolder - Select "Deploy to Web App..."
- Choose your subscription and App Service
- Confirm deployment
- Right-click the
Using Visual Studio
- Right-click the project in Solution Explorer
- Select Publish
- Choose Azure > Azure App Service (Linux)
- Select or create an App Service
- Click Publish
Using Azure CLI
# Login to Azure
az login
# Create resource group
az group create --name myResourceGroup --location eastus
# Create App Service Plan
az appservice plan create \
--name myAppServicePlan \
--resource-group myResourceGroup \
--sku B1 \
--is-linux
# Create Web App
az webapp create \
--name myAgilityApp \
--resource-group myResourceGroup \
--plan myAppServicePlan \
--runtime "DOTNET|10.0"
# Configure settings
az webapp config appsettings set \
--name myAgilityApp \
--resource-group myResourceGroup \
--settings \
AppSettings__InstanceGUID=your-guid \
AppSettings__SecurityKey=your-key \
AppSettings__FetchAPIKey=defaultlive.your-key \
AppSettings__PreviewAPIKey=defaultpreview.your-key
# Enable WebSockets (required for Blazor)
az webapp config set \
--name myAgilityApp \
--resource-group myResourceGroup \
--web-sockets-enabled true
# Deploy code
az webapp deployment source config-local-git \
--name myAgilityApp \
--resource-group myResourceGroup
# Push to deploy
git remote add azure <deployment-url>
git push azure main
Using GitHub Actions
Create .github/workflows/azure-deploy.yml:
name: Deploy to Azure
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: |
cd Agility.NET.Blazor.Starter
dotnet restore
npm install
- name: Build
run: |
cd Agility.NET.Blazor.Starter
dotnet publish -c Release -o ./publish
- name: Deploy to Azure
uses: azure/webapps-deploy@v3
with:
app-name: ${{ secrets.AZURE_APP_NAME }}
publish-profile: ${{ secrets.AZURE_PUBLISH_PROFILE }}
package: ./Agility.NET.Blazor.Starter/publish
Setup:
- Go to Azure Portal > Your App Service > Deployment Center
- Download the publish profile
- Add it as a GitHub secret named
AZURE_PUBLISH_PROFILE - Add your app name as
AZURE_APP_NAME
Post-Deployment Configuration
1. Configure Environment Variables
In Azure Portal:
- Go to your App Service
- Navigate to Settings > Environment variables
- Add application settings:
| Name | Value |
|---|---|
AppSettings__InstanceGUID | Your instance GUID |
AppSettings__SecurityKey | Your security key |
AppSettings__FetchAPIKey | Your live API key |
AppSettings__PreviewAPIKey | Your preview API key |
AppSettings__Locales | en-us (or your locales) |
AppSettings__ChannelName | website |
AppSettings__CacheInMinutes | 5 |
- Click Save and confirm restart
2. Configure Webhooks
Set up cache invalidation in Agility CMS:
- Go to Settings > Webhooks in Agility CMS
- Click Add Webhook
- Configure:
- Name: Azure Cache Invalidation
- URL:
https://your-app.azurewebsites.net/api/revalidate - Events: Content Published, Page Published
- Save the webhook
3. Configure Preview URLs
Enable content preview:
- Go to Settings > Preview URLs in Agility CMS
- Add a preview URL:
- Name: Azure Preview
- URL:
https://your-app.azurewebsites.net{path}?agilitypreviewkey={previewkey}
- Save
4. Custom Domain (Optional)
- Go to Settings > Custom domains in Azure Portal
- Click Add custom domain
- Enter your domain name
- Add the required DNS records
- Add an SSL certificate (free managed certificate available)
Monitoring and Troubleshooting
Enable Application Insights
az webapp config appsettings set \
--name myAgilityApp \
--resource-group myResourceGroup \
--settings APPLICATIONINSIGHTS_CONNECTION_STRING=your-connection-string
View Logs
Log Stream (real-time):
az webapp log tail --name myAgilityApp --resource-group myResourceGroup
In Azure Portal:
- Go to your App Service
- Navigate to Monitoring > Log stream
Common Issues
502 Bad Gateway
- Check application logs for startup errors
- Verify .NET version matches your app
- Ensure all environment variables are set
SignalR/WebSocket Errors (Blazor)
-
Verify WebSockets are enabled:
az webapp config show --name myAgilityApp --resource-group myResourceGroup \ --query webSocketsEnabled -
Enable if needed:
az webapp config set --name myAgilityApp --resource-group myResourceGroup \ --web-sockets-enabled true
Content Not Loading
- Verify API keys are correct
- Check Agility CMS has published content
- Verify
ChannelNamematches your sitemap
Slow Cold Starts
Enable AlwaysOn to prevent cold starts:
az webapp config set --name myAgilityApp --resource-group myResourceGroup \
--always-on true
Scaling
Vertical Scaling (Scale Up)
Change to a larger SKU:
az appservice plan update --name myAppServicePlan \
--resource-group myResourceGroup \
--sku S1
Horizontal Scaling (Scale Out)
Add more instances:
az appservice plan update --name myAppServicePlan \
--resource-group myResourceGroup \
--number-of-workers 3
Auto-Scaling
Configure auto-scale rules in Azure Portal:
- Go to your App Service Plan
- Navigate to Settings > Scale out
- Configure rules based on CPU, memory, or HTTP queue length
Cost Optimization
Development/Testing
- Use B1 SKU (~$13/month)
- Scale down when not in use
- Use deployment slots for staging
Production
- Use S1 or higher for production workloads
- Enable CDN for static assets
- Use Azure Front Door for global distribution
Free Tier Limitations
The F1 (Free) tier does not support:
- WebSockets (required for Blazor Interactive Server)
- AlwaysOn (causes cold starts)
- Custom domains with SSL
Security Checklist
- Environment variables set (not in code)
- HTTPS enforced
- TLS 1.2 minimum
- API keys are not exposed
- Webhook endpoint is secured
- Application Insights enabled for monitoring
Next Steps
- Configuration - All configuration options
- Migration Guide - Upgrading from older versions
- Blazor Starter - Blazor-specific deployment notes
- MVC Starter - MVC-specific deployment notes