Comment nous avons déployé et mis à l'échelle sur Azure : un guide de production
Le passage à Azure Container Apps a transformé notre vitesse de livraison. Voici la configuration exacte que nous utilisons chez Fygurs — container registry, scaling par environnement, et déploiements automatisés déclenchés par un push GitHub — avec les leçons apprises après avoir d'abord mal fait.
Avant notre migration vers Azure Container Apps, déployer un service signifiait se connecter en SSH à une VM et espérer que l'environnement corresponde à la staging. Ce n'était pas un processus — c'était un rituel. Voici la configuration Azure exacte que nous utilisons chez Fygurs : container registry, Container Apps avec ingress interne entre services, et un pipeline GitHub Actions qui déploie à chaque merge. Zéro étape manuelle.
La Plateforme Cloud Azure
Microsoft Azure fournit des services de cloud computing à la demande. Au lieu de gérer des serveurs physiques, vous louez des ressources de calcul, de stockage et de réseau qui s'adaptent automatiquement à la demande.
Avantages Clés
- Paiement à l'usage : Ne payez que les ressources consommées
- Disponibilité mondiale : Déployez dans plus de 60 régions dans le monde
- Services managés : Azure gère les patches, le scaling et la maintenance
- Sécurité : Conformité intégrée, chiffrement et gestion des identités
Les Groupes de Ressources Azure
Un groupe de ressources est un conteneur logique qui regroupe les ressources Azure liées entre elles. Toutes les ressources d'une solution (conteneurs, bases de données, stockage) sont regroupées pour une gestion unifiée.
STRUCTURE D'UN GROUPE DE RESSOURCES ┌──────────────────────────────────────────────────┐ │ Groupe de Ressources : mon-projet │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │ Container │ │ Container │ │ Stockage │ │ │ │ App 1 │ │ App 2 │ │ Blob │ │ │ └────────────┘ └────────────┘ └────────────┘ │ │ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │ Container │ │ PostgreSQL │ │ RabbitMQ │ │ │ │ Registry │ │ Database │ │ Service │ │ │ └────────────┘ └────────────┘ └────────────┘ │ │ │ └──────────────────────────────────────────────────┘
Créer un Groupe de Ressources
az group create \
--name mon-projet \
--location westeurope
Avantages des Groupes de Ressources
- Gestion du cycle de vie : Supprimez toutes les ressources en supprimant le groupe
- Contrôle d'accès : Appliquez le RBAC au niveau du groupe
- Suivi des coûts : Surveillez les dépenses par groupe de ressources
- Étiquetage : Organisez les ressources avec des balises de métadonnées
- Verrous : Empêchez la suppression accidentelle des ressources critiques
Azure Container Registry
Azure Container Registry (ACR) est un service de registre Docker managé pour stocker et gérer les images de conteneurs. Il s'intègre parfaitement avec Azure Container Apps et Kubernetes.
FLUX DU CONTAINER REGISTRY
┌─────────────┐ ┌─────────────────┐ ┌─────────────┐
│ GitHub │ │ Azure │ │ Container │
│ Actions │─────▶│ Container │─────▶│ Apps │
│ (CI/CD) │ push │ Registry │ pull │ (Runtime) │
└─────────────┘ └─────────────────┘ └─────────────┘
│
┌──────┴──────┐
│ Images │
│ - api:v1 │
│ - web:v2 │
│ - worker │
└─────────────┘
Niveaux de Service
- Basic : Point d'entrée pour le développement et les tests
- Standard : Charges de production avec un débit plus élevé
- Premium : Géo-réplication, confiance de contenu, endpoints privés
Fonctionnalités de Sécurité
- TLS 1.2 : Transferts d'images chiffrés
- Microsoft Entra ID : Authentification basée sur l'identité
- Principaux de service : Authentification CI/CD automatisée
- RBAC : Contrôle granulaire des permissions
- Analyse d'images : Intégration Microsoft Defender
Créer un Container Registry
az acr create \
--resource-group mon-projet \
--name monregistry \
--sku Standard
Pousser des Images
az acr login --name monregistry
docker tag mon-app:latest monregistry.azurecr.io/mon-app:v1
docker push monregistry.azurecr.io/mon-app:v1
Azure Container Apps
Azure Container Apps est une plateforme de conteneurs serverless qui exécute des microservices sans gérer l'infrastructure. Elle gère automatiquement le scaling, l'équilibrage de charge et les certificats HTTPS.
ARCHITECTURE CONTAINER APPS
┌──────────────────────────────────────────────┐
│ Environnement Container Apps │
│ │
│ ┌─────────┐ ┌─────────┐ │
│ │ API │ TCP │ Worker │ │
│ │ Gateway │───────▶│ Service │ │
│ │ :443 │ │ :3001 │ │
│ └─────────┘ └────┬────┘ │
│ │ │ │
│ │ TCP │ AMQP │
│ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ │
│ │ Auth │ │ RabbitMQ│ │
│ │ Service │ │ :5672 │ │
│ │ :3002 │ └─────────┘ │
│ └─────────┘ │
│ │
└──────────────────────────────────────────────┘
▲
│ HTTPS
│
Internet
Fonctionnalités Clés
- Scaling serverless : Scale jusqu'à zéro ou des centaines de réplicas
- Intégration KEDA : Scale basé sur le trafic HTTP, le CPU, la mémoire ou la profondeur de file
- Ingress intégré : HTTPS et TCP sans configuration supplémentaire
- Découverte de services : DNS interne pour la communication entre microservices
- Traffic splitting : Déploiements blue/green et tests A/B
- Intégration Dapr : Patterns microservices prêts à l'emploi
Configuration de l'Ingress
L'ingress contrôle comment le trafic atteint vos container apps. Il définit si l'app est accessible publiquement ou uniquement depuis l'environnement.
TYPES D'INGRESS
Ingress Externe Ingress Interne
(Accès Public) (Accès Privé)
Internet Environnement Container Apps
│ ┌──────────────────────────┐
│ HTTPS │ │
▼ │ Service A ──▶ Service B │
┌───────────────┐ │ │ │
│ API Gateway │ │ └────────▶ Svc C │
│ (externe) │ │ │
└───────────────┘ └──────────────────────────┘
Ingress Externe
Expose l'app à l'internet public. Azure fournit un nom de domaine complet (FQDN) et des certificats TLS automatiques. Utilisez --ingress external pour les API gateways et les applications web.
Ingress Interne
Accessible uniquement depuis l'environnement Container Apps. Les autres apps y accèdent via le DNS interne en utilisant le nom de l'app. Utilisez --ingress internal pour les microservices.
Les services internes sont accessibles par leur nom : http://auth-service ou tcp://auth-service:3002
Protocoles de Transport
- HTTP/HTTPS : Défaut pour les applications web, terminaison TLS automatique
- TCP : Requis pour les microservices NestJS, RabbitMQ, PostgreSQL, Redis. Utilisez
--transport tcp
Le Problème du Cold Start
Quand une Container App scale à zéro, la prochaine requête doit attendre le démarrage du conteneur. Ce cold start peut prendre 15 à 30 secondes, rendant le scale-to-zero inadapté aux APIs orientées utilisateurs.
CHRONOLOGIE DU COLD START
Scale à Zéro Première Requête Conteneur Prêt
│ │ │
▼ ▼ ▼
─────●──────────────────────●──────────────────────●─────▶
│ │ │
│ Temps d'inactivité │ 15-30 secondes │
│ (sans coût) │ (utilisateur attend)│
La solution est de maintenir au moins un réplica actif avec --min-replicas 1. Les temps de réponse descendent à ~100-150ms. Le coût de la plus petite configuration (0,25 CPU / 512Mo) reste inférieur à 10€/mois, un compromis raisonnable pour éliminer les cold starts sur les APIs de production.
Créer une Container App
az containerapp create \
--name api-gateway \
--resource-group mon-projet \
--environment mon-environnement \
--image monregistry.azurecr.io/api:v1 \
--target-port 3000 \
--ingress external \
--min-replicas 1 \
--max-replicas 10 \
--registry-server monregistry.azurecr.io \
--registry-username $REGISTRY_USERNAME \
--registry-password $REGISTRY_PASSWORD \
--env-vars \
DATABASE_URL=$DATABASE_URL \
JWT_SECRET=secretref:jwt-secret
Microservice Interne (TCP)
az containerapp create \
--name auth-service \
--resource-group mon-projet \
--environment mon-environnement \
--image monregistry.azurecr.io/auth:v1 \
--target-port 3002 \
--ingress internal \
--transport tcp \
--min-replicas 1 \
--max-replicas 5
Pipeline CD avec GitHub Actions
Le déploiement continu automatise le processus de build, push et déploiement des conteneurs à chaque merge de code.
FLUX DU PIPELINE CD
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ GitHub │ │ Build │ │ Push │ │ Deploy │
│ Push │───▶│ Docker │───▶│ vers │───▶│ vers ACA │
│ │ │ Image │ │ ACR │ │ │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ Secrets GitHub │
│ AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID │
│ REGISTRY_SERVER, REGISTRY_USERNAME, REGISTRY_PASSWORD │
│ DATABASE_URL, JWT_SECRET, RABBITMQ_HOST, ... │
└──────────────────────────────────────────────────────────┘
Structure du Workflow
name: CD
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
env:
AZURE_CONTAINER_REGISTRY: ${{ secrets.AZURE_CONTAINER_REGISTRY }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
steps:
- name: Checkout du code
uses: actions/checkout@v4
- name: Configurer Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Installer les dépendances
run: npm install
- name: Se connecter à Azure
uses: azure/login@v2
with:
creds: '{"clientId":"${{ secrets.AZURE_CLIENT_ID }}","clientSecret":"${{ secrets.AZURE_CLIENT_SECRET }}","tenantId":"${{ secrets.AZURE_TENANT_ID }}"}'
- name: Builder l'image Docker
run: |
docker build --platform=linux/amd64 \
-t mon-service \
-f apps/mon-service/Dockerfile .
docker tag mon-service \
${{ env.AZURE_CONTAINER_REGISTRY }}/mon-service:${{ github.sha }}
- name: Se connecter à l'ACR
run: |
az acr login --name ${{ env.REGISTRY_USERNAME }}
- name: Pousser vers l'ACR
run: |
docker push ${{ env.AZURE_CONTAINER_REGISTRY }}/mon-service:${{ github.sha }}
- name: Déployer vers Container Apps
run: |
az containerapp update \
--name mon-service \
--resource-group mon-projet \
--image ${{ env.AZURE_CONTAINER_REGISTRY }}/mon-service:${{ github.sha }}
Utilisez az containerapp create pour le déploiement initial, puis az containerapp update pour les déploiements suivants afin de mettre à jour l'image.
Stratégie de Tagging des Images
- ${{ github.sha }} : Hash de commit unique pour la traçabilité
- latest : Pointe toujours vers le build le plus récent
- v1.0.0 : Versionnage sémantique pour les releases
Bonnes Pratiques
Sécurité
- Ne codez jamais les secrets en dur : Utilisez les Secrets GitHub et les références secrètes Azure
- Ingress interne : Exposez uniquement l'API gateway publiquement
- Principaux de service : Utilisez des identités dédiées pour le CI/CD
- TLS partout : Azure fournit des certificats HTTPS automatiques
Optimisation des Coûts
- Scale à zéro : À utiliser pour les jobs en arrière-plan et les tâches planifiées, pas pour les APIs orientées utilisateurs (cold starts)
- Dimensionnez les ressources : Commencez petit, scalez en fonction des métriques
- Groupes de ressources : Balisez et surveillez les coûts par environnement
Fiabilité
- Plusieurs réplicas : Minimum 2 réplicas pour la production
- Health probes : Configurez les vérifications de liveness et readiness
- Gestion des révisions : Conservez les révisions précédentes pour un rollback rapide
Conclusion
Les services de conteneurs Azure fournissent une plateforme complète pour le déploiement de microservices. Les groupes de ressources organisent l'infrastructure, Container Registry stocke les images de façon sécurisée, et Container Apps exécute les workloads avec un scaling automatique. Combiné à GitHub Actions, vous obtenez un pipeline de déploiement entièrement automatisé du push de code à la production.
La nature serverless de Container Apps signifie que vous vous concentrez sur le code applicatif pendant qu'Azure gère les préoccupations d'infrastructure. Le réseau interne sécurise les microservices, tandis que l'ingress externe expose uniquement ce qui doit l'être. Cette architecture passe du développement à la production sans changer les patterns de déploiement.
Lecture Associée
Ces articles étendent les patterns de déploiement Azure couverts ici :
- Livrer Plus Vite avec des Pipelines Automatisés : CI/CD avec GitHub Actions — le workflow GitHub Actions qui déclenche les déploiements Azure Container Apps décrits dans ce guide.
- Scaler les Applications dans le Cloud : Kubernetes et GitOps en Pratique — comment Kubernetes et ArgoCD complètent Azure pour les équipes qui ont besoin d'une gestion de cluster déclarative et auditable.
Consultez les projets Fygurs et infrastructure cloud pour explorer les systèmes de production alimentés par cette configuration Azure.
Écrit par

Tech Lead et Ingénieur Full Stack pilotant une équipe de 5 ingénieurs chez Fygurs (Paris, Remote) sur un SaaS cloud-native Azure. Diplômé de 1337 Coding School (42 Network / UM6P). Écrit sur l'architecture, l'infrastructure cloud et le leadership technique.