Skip to main content

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>.

Estimated Time

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:

  1. Generates .github/workflows/deploy-demo.yml if it doesn't exist
  2. Sets APP_NAME in the workflow to your vertical's name
  3. 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:

SecretDescription
AZUREAPPSERVICE_CLIENTIDAzure AD app registration client ID
AZUREAPPSERVICE_TENANTIDAzure AD tenant ID
AZUREAPPSERVICE_SUBSCRIPTIONIDAzure subscription ID
AZURE_RESOURCE_GROUPrg-demo-infrastructure
AZURE_WEBAPP_NAMEapp-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 verticalApps array order)
  • Process management (PM2-like startup)

Build Process

The GitHub Actions workflow:

  1. Checks out your code
  2. Installs dependencies (npm ci)
  3. Builds with subpath: APP_BASE_PATH=/my-vertical npm run build
  4. Packages the standalone output
  5. Deploys via az webapp deploy --type zip
  6. 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_NAME in the workflow matches the demo-infra registration
  • Verify APP_BASE_PATH is set correctly in Azure App Settings
  • Check the Express router is restarted: az webapp restart ...

Authentication redirect fails

  • Ensure AUTH_URL includes 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_PATH and Express router configuration
  • CI/CD pipeline: GitHub Actions to Azure deployment flow
  • Infrastructure registration: Adding your app to demo-infra

Next Steps