Tutorial: Deploy to Azure
Deploy your vertical application to Azure App Service using the multi-app deployment architecture. Your app will be available at https://app-demo-eai-dev.azurewebsites.net/<your-app-name>.
20 minutes -- This tutorial covers Azure App Service deployment, demo-infra registration, and GitHub Actions CI/CD setup.
What You'll Build
- A production deployment on Azure App Service
- CI/CD pipeline with GitHub Actions for automatic deployments
- Multi-app subpath routing configuration
- Environment variable and secrets management
Prerequisites
Before starting this tutorial, make sure you have:
- A working vertical project (see Build a Task Tracker)
- GitHub repository created for your project
- Azure subscription with access to the shared App Service
- GitHub Secrets configured (or admin access to set them)
- Completed the Prerequisites setup
Step 1: Register Your App in Demo-Infra
Add your app to the shared infrastructure configuration. In the demo-infra repo, edit infra/main.bicepparam:
param verticalApps = [
'existing-app'
'my-vertical' // <- Add your app here
]
This provisions:
- Port assignment (auto-incremented: 3001, 3002, ...)
- Express router entry for subpath routing
- Startup script configuration
Step 2: Configure Deployment with eai CLI
The fastest way to set up deployment:
eai deploy setup --repo eai-tools/my-vertical
This command:
- Generates
.github/workflows/deploy-demo.ymlif it doesn't exist - Sets
APP_NAMEin the workflow to your vertical's name - Configures GitHub Secrets for Azure authentication
Manual Configuration
If you prefer to configure manually, edit .github/workflows/deploy-demo.yml:
env:
APP_NAME: my-vertical # Must match demo-infra registration
Configure these GitHub Secrets in Settings > Environments > demo:
| Secret | Description |
|---|---|
AZUREAPPSERVICE_CLIENTID | Azure AD app registration client ID |
AZUREAPPSERVICE_TENANTID | Azure AD tenant ID |
AZUREAPPSERVICE_SUBSCRIPTIONID | Azure subscription ID |
AZURE_RESOURCE_GROUP | rg-demo-infrastructure |
AZURE_WEBAPP_NAME | app-demo-eai-dev |
Step 3: Set Environment Variables
Your vertical needs runtime environment variables in Azure App Service. These are set through the Azure Portal or CLI:
# Required variables
az webapp config appsettings set \
--resource-group rg-demo-infrastructure \
--name app-demo-eai-dev \
--settings \
BASE_URL_PUBLIC_API=https://test-api.myenterprise.ai \
TENANT_tracker_ID=<your-tenant-id> \
WORKFLOW_tracker_ID=<your-workflow-id> \
ENTRA_TENANT_NAME=eaidevmyentepriseai \
ENTRA_TENANT_ID=<entra-tenant-id> \
ENTRA_CLIENT_ID=<client-id> \
ENTRA_CLIENT_SECRET=<client-secret> \
AUTH_SECRET=$(openssl rand -base64 32) \
APP_BASE_PATH=/my-vertical
Step 4: Deploy
Push to main to trigger automatic deployment:
git add .
git commit -m "Ready for deployment"
git push origin main
Or trigger manually:
eai deploy trigger
Step 5: Verify
Check deployment status:
eai deploy status
Then visit your app:
https://app-demo-eai-dev.azurewebsites.net/my-vertical
Run platform checks:
eai verify
How Multi-App Deployment Works
Azure App Service (app-demo-eai-dev)
|-- Express Router (port 8080)
| |-- /app-one -> localhost:3001
| |-- /app-two -> localhost:3002
| |-- /my-vertical -> localhost:3003
|-- app-one/ (standalone Next.js)
|-- app-two/ (standalone Next.js)
|-- my-vertical/ (standalone Next.js)
Each vertical runs as a standalone Next.js server on its own port. The Express router handles:
- Subpath routing (
/my-vertical/*->localhost:3003) - Port assignment (from
verticalAppsarray order) - Process management (PM2-like startup)
Build Process
The GitHub Actions workflow:
- Checks out your code
- Installs dependencies (
npm ci) - Builds with subpath:
APP_BASE_PATH=/my-vertical npm run build - Packages the standalone output
- Deploys via
az webapp deploy --type zip - Restarts the App Service
The basePath Configuration
next.config.ts reads APP_BASE_PATH to configure Next.js subpath routing:
const nextConfig = {
basePath: process.env.APP_BASE_PATH || '',
assetPrefix: process.env.APP_BASE_PATH || '',
output: 'standalone',
};
This ensures all routes and static assets are served under /my-vertical/.
Troubleshooting
App returns 404
- Check that
APP_NAMEin the workflow matches the demo-infra registration - Verify
APP_BASE_PATHis set correctly in Azure App Settings - Check the Express router is restarted:
az webapp restart ...
Authentication redirect fails
- Ensure
AUTH_URLincludes the full base path:https://app-demo-eai-dev.azurewebsites.net/my-vertical - Verify Entra CIAM redirect URIs include your deployed URL
Build fails
Run locally first:
APP_BASE_PATH=/my-vertical npm run build
Environment variables not loading
az webapp config appsettings list \
--resource-group rg-demo-infrastructure \
--name app-demo-eai-dev \
--query "[?contains(name, 'TENANT')]"
What You Learned
- Multi-app architecture: How multiple verticals share one App Service
- Subpath routing:
APP_BASE_PATHand Express router configuration - CI/CD pipeline: GitHub Actions to Azure deployment flow
- Infrastructure registration: Adding your app to demo-infra
Next Steps
- Architecture Overview -- Full platform architecture
- Environment Configuration -- All environment variables explained
- Troubleshooting Guide -- Common issues and fixes