Skip to content
Learni
Voir tous les tutoriels
Cloud Computing

Comment déployer une app scalable sur Azure App Service en 2026

Read in English

Introduction

Azure App Service est la plateforme PaaS leader pour héberger des applications web, mobiles et API sans gérer l'infrastructure sous-jacente. En 2026, avec l'essor de l'IA et des workloads hybrides, maîtriser App Service avancé signifie implémenter des déploiements zero-downtime via slots, autoscaling intelligent avec KEDA, et CI/CD natif GitHub. Ce tutoriel avancé guide un développeur senior à travers la création d'une app Node.js Express, son déploiement via Azure CLI et Bicep, configuration de slots pour blue-green deployments, et scaling basé sur métriques custom.

Pourquoi c'est crucial ? Les apps modernes subissent des pics imprévisibles ; App Service excelle avec son intégration seamless à Azure Monitor, Application Insights et Virtual Network. Vous économiserez des heures sur les ops en automatisant tout. À la fin, votre app sera production-ready, scalable à 1000+ instances, avec monitoring proactif. Prêt à passer pro ? (128 mots)

Prérequis

  • Compte Azure gratuit ou payant (crédit suffisant pour App Service Plan Premium)
  • Azure CLI 2.65+ installé
  • Node.js 20+ et npm
  • GitHub account avec repo privé
  • VS Code avec extensions Azure App Service et Bicep
  • Connaissances avancées en TypeScript, DevOps et ARM/Bicep

Créer l'application Node.js de base

src/server.ts
import express, { Request, Response, NextFunction } from 'express';
import helmet from 'helmet';
import cors from 'cors';

const app = express();
const PORT = process.env.PORT || 8080;

app.use(helmet());
app.use(cors());
app.use(express.json());

app.get('/health', (req: Request, res: Response) => {
  res.status(200).json({ status: 'healthy', timestamp: new Date().toISOString() });
});

app.get('/api/metrics', (req: Request, res: Response) => {
  // Simulate CPU-intensive metric for scaling demo
  const load = Math.random() * 100;
  res.json({ cpuLoad: load, requests: process.env.REQUEST_COUNT || '0' });
});

app.post('/api/increment', (req: Request, res: Response) => {
  const count = (parseInt(process.env.REQUEST_COUNT || '0') + 1).toString();
  process.env.REQUEST_COUNT = count;
  res.json({ incremented: count });
});

app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
  console.error(err.stack);
  res.status(500).json({ error: 'Internal Server Error' });
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Ce serveur Express TypeScript inclut sécurité (Helmet, CORS), health check pour liveness/readiness probes, et endpoints pour simuler charge CPU/requests. Les variables d'env comme REQUEST_COUNT persistent via App Settings. Piège : Toujours typer Request/Response pour éviter erreurs runtime ; testez localement avec npx ts-node src/server.ts.

Générer package.json et tsconfig.json

package.json
{
  "name": "azure-app-service-demo",
  "version": "1.0.0",
  "main": "dist/server.js",
  "scripts": {
    "build": "tsc",
    "start": "node dist/server.js",
    "dev": "ts-node src/server.ts"
  },
  "dependencies": {
    "express": "^4.19.2",
    "helmet": "^7.1.0",
    "cors": "^2.8.5"
  },
  "devDependencies": {
    "@types/express": "^4.17.21",
    "@types/node": "^20.11.19",
    "ts-node": "^10.9.2",
    "typescript": "^5.3.3"
  }
}

Ce package.json supporte build TS->JS pour Azure (dist/), avec scripts pour dev/prod. Installez via npm i puis npm run build. Piège : Oubliez pas @types pour IntelliSense ; Azure détecte auto Node via engine dans package.json (ajoutez "engines": {"node": "20.x"} si besoin).

Installer Azure CLI et créer resource group

setup-azure.sh
#!/bin/bash
# Installer Azure CLI si pas présent
curl -sL https://aka.ms/InstallAzureCLIDeb | bash

# Login (utilisez az login --use-device-code pour headless)
az login

# Variables
RESOURCE_GROUP="rg-appservice-demo-$(date +%Y%m%d)"
LOCATION="westeurope"
APP_NAME="demo-app-$(date +%s)"

# Créer resource group
az group create --name $RESOURCE_GROUP --location $LOCATION

echo "Resource group créé: $RESOURCE_GROUP"
echo "App name généré: $APP_NAME"
export RESOURCE_GROUP=$RESOURCE_GROUP
export APP_NAME=$APP_NAME

Ce script bash installe Azure CLI, logue et crée un RG unique avec timestamp. Exécutez bash setup-azure.sh puis sourcez exports. Piège : Utilisez westeurope pour latence FR ; vérifiez quotas RG avec az group list.

Déployer App Service Plan et app via CLI

deploy-cli.sh
#!/bin/bash
source setup-azure.sh
exported

# Créer App Service Plan Premium V3 (autoscaling)
az appservice plan create \
  --name ${APP_NAME}-plan \
  --resource-group $RESOURCE_GROUP \
  --sku P1V3 \
  --is-linux

# Créer web app Node.js
az webapp create \
  --resource-group $RESOURCE_GROUP \
  --plan ${APP_NAME}-plan \
  --name $APP_NAME \
  --runtime "NODE|20-lts" \
  --deployment-local-git

# Config app settings pour scaling demo
az webapp config appsettings set \
  --resource-group $RESOURCE_GROUP \
  --name $APP_NAME \
  --settings REQUEST_COUNT=0 WEBSITE_NODE_DEFAULT_VERSION=20

# Build et ZIP deploy
npm run build
zip -r app.zip .
az webapp deployment source config-zip \
  --resource-group $RESOURCE_GROUP \
  --name $APP_NAME \
  --src app.zip

# URL de l'app
echo "App déployée: https://${APP_NAME}.azurewebsites.net/health"

Ce script crée un Plan PremiumV3 Linux (scale-out auto), webapp Node20, set env vars, build/zip et déploie. Testez /health. Piège : PremiumV3 requis pour slots/custom scaling ; ZIP max 2GB, utilisez Git pour >.

Template Bicep pour infrastructure IaC

main.bicep
param location string = resourceGroup().location
param appName string

resource appServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = {
  name: '${appName}-plan'
  location: location
  sku: {
    name: 'P1V3'
    tier: 'PremiumV3'
  }
  kind: 'linux'
}

resource appService 'Microsoft.Web/sites@2023-01-01' = {
  name: appName
  location: location
  properties: {
    serverFarmId: appServicePlan.id
    siteConfig: {
      linuxFxVersion: 'NODE|20-lts'
      appSettings: [
        { name: 'REQUEST_COUNT', value: '0' }
        { name: 'WEBSITE_RUN_FROM_PACKAGE', value: '1' }
      ]
    }
  }
}

output appUrl string = 'https://${appName}.azurewebsites.net'

Ce template Bicep déclare Plan et App Service avec settings. Déployez via az deployment group create --resource-group $RESOURCE_GROUP --template-file main.bicep --parameters appName=$APP_NAME. Piège : WEBSITE_RUN_FROM_PACKAGE=1 pour run-from-zip sans warmup ; idempotent, réutilisable en pipelines.

Workflow GitHub Actions pour CI/CD

.github/workflows/deploy.yml
name: Deploy to Azure App Service

on:
  push:
    branches: [ main ]

env:
  AZURE_WEBAPP_NAME: ${{ secrets.AZURE_WEBAPP_NAME }}
  AZURE_WEBAPP_PACKAGE_PATH: 'app.zip'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Setup Node
      uses: actions/setup-node@v4
      with:
        node-version: '20'
    - run: npm ci
    - run: npm run build
    - run: zip -r ${{ env.AZURE_WEBAPP_PACKAGE_PATH }} .
    - uses: actions/upload-artifact@v4
      with:
        name: app
        path: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
  deploy:
    runs-on: ubuntu-latest
    needs: build
    steps:
    - uses: azure/login@v2
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}
    - download: current
      name: Download
      uses: actions/download-artifact@v4
      with:
        name: app
    - uses: azure/webapps-deploy@v3
      with:
        app-name: ${{ env.AZURE_WEBAPP_NAME }}
        package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}

Ce workflow build/zip sur push main, utilise OIDC Azure login (via secrets AZURE_CREDENTIALS JSON), déploie ZIP. Ajoutez secrets GitHub. Piège : run-from-package auto avec ZIP ; testez avec act localement.

Créer slot de staging et swap

slots.sh
#!/bin/bash
source setup-azure.sh
exported

# Créer production slot (défaut)
# Créer staging slot
az webapp deployment slot create \
  --name $APP_NAME \
  --resource-group $RESOURCE_GROUP \
  --slot staging

# Déployer sur staging (même ZIP)
zip -r staging.zip .
az webapp deployment source config-zip \
  --resource-group $RESOURCE_GROUP \
  --name $APP_NAME \
  --slot staging \
  --src staging.zip

# Test staging
curl https://${APP_NAME}-staging.azurewebsites.net/health

# Swap zero-downtime
az webapp deployment slot swap \
  --name $APP_NAME \
  --resource-group $RESOURCE_GROUP \
  --slot staging \
  --target-slot production

echo "Swappé ! Prod: https://${APP_NAME}.azurewebsites.net/health"

Slots permettent blue-green : déploie/test sur staging, swap atomique. Piège : Traffic % configurable via az webapp traffic ... ; warmup auto sur Premium.

Bonnes pratiques

  • Utilisez toujours slots pour zero-downtime et A/B testing.
  • Implémentez KEDA scaling sur métriques custom (CPU >80%, requests/sec) via az monitor autoscale ....
  • Intégrez Application Insights : az webapp config appsettings set APPINSIGHTS_INSTRUMENTATIONKEY=....
  • VNet integration pour private endpoints : az webapp vnet-integration add.
  • Secrets en Key Vault : Reference via @Microsoft.KeyVault(...) en Bicep.

Erreurs courantes à éviter

  • Oublier Premium Plan : Basic/Shared bloquent slots/autoscale ; upgrade tôt.
  • ZIP trop gros : >2GB crash ; passez à Git/Containers.
  • Pas de health checks : Probes échouent, app marked unhealthy ; exposez /health.
  • Secrets hardcoded : Utilisez App Settings ou KV, jamais en code.

Pour aller plus loin