RO EN

CI/CD profesionist cu GitHub Actions (4): deployment slots pentru zero-downtime

CI/CD profesionist cu GitHub Actions (4): deployment slots pentru zero-downtime ✨ Imagine generată cu AI
Doru Bulubasa
08 septembrie 2026
38 vizualizări

Până acum avem un pipeline serios: build o singură dată, promovare prin medii cu approval gates și infrastructură definită în cod cu Bicep. Mai rămâne un moment neplăcut – chiar cel în care aplicația ajunge la clienți.

Când faci deploy direct peste producție, App Service-ul copiază fișierele noi și repornește aplicația. Iar între „a repornit” și „e gata să răspundă” sunt câteva secunde bune în care utilizatorii pot primi erori.

Un deploy care îți pică site-ul pentru zece secunde la fiecare release nu e un deploy profesionist – e o întrerupere programată.

🎯 De ce un deploy direct produce downtime

Chiar dacă totul e automatizat, un deploy direct peste instanța de producție înseamnă:

  • Fișierele se suprascriu – cât timp se copiază, aplicația e într-o stare inconsistentă.

  • Aplicația repornește – procesul vechi se oprește, cel nou pornește.

  • Cold start – primul request găsește un app rece: JIT, conexiuni la baza de date, cache gol. Răspunsurile sunt lente sau pică.

Pentru un site cu trafic real, asta înseamnă erori vizibile la fiecare release. Soluția Azure pentru problema asta se numește deployment slots.


🔀 Ce sunt deployment slots

Un deployment slot e o instanță live, separată, a aceluiași App Service. Pe lângă slotul principal (production) mai creezi unul (staging), cu propriul hostname, dar care rulează pe același App Service Plan.

Ideea de bază:

  • Deployezi noua versiune în slotul staging, nu direct în producție.

  • Îl lași să se „încălzească” – pornește, se conectează la baza de date, își umple cache-ul.

  • Verifici că e sănătos pe hostname-ul de staging.

  • Faci swap – production pointează instant către instanța deja caldă.

Nu deployezi în producție. Deployezi lângă producție, încălzești, apoi comuți.

O notă importantă: sloturile sunt disponibile de la tier-ul Standard în sus (S1, P1v3 etc.). Pe Basic sau Free nu ai sloturi – de aceea, în Bicep-ul din partea 3, producția era pe un plan Premium.


⚡ De ce swap-ul dă zero downtime real

Aici e cheia. Swap-ul nu copiază fișiere și nu repornește nimic în momentul comutării. E doar o schimbare de routing – traficul care mergea către instanța veche e redirecționat către cea nouă, care e deja pornită și caldă.

Diferența față de un deploy direct:

  • Deploy direct: repornire + cold start pe instanța de producție, cu utilizatori pe ea.

  • Slot swap: instanța nouă e deja caldă înainte de swap; comutarea e aproape instantanee, fără cold start vizibil.


🔥 Warm-up și setări sticky

Înainte de a finaliza swap-ul, Azure poate trimite request-uri către slotul nou ca să-l pornească complet – asta e warm-up-ul (applicationInitialization). Abia după ce slotul răspunde, swap-ul se încheie.

Al doilea concept important e sticky settings. Normal, la swap, setările aplicației se mută împreună cu codul. Dar unele setări trebuie să rămână lipite de slot – de exemplu, vrei ca slotul staging să folosească mereu connection string-ul de staging, nu să-l ducă în producție la swap.

În Azure, marchezi un app setting sau connection string ca „deployment slot setting” – atunci rămâne fix pe slotul lui și nu se mută la swap.


🧱 Slotul, definit în Bicep

Fiind tot infrastructură, slotul se definește curat în Bicep, ca resursă copil a web app-ului (legându-ne de partea 3):

resource stagingSlot 'Microsoft.Web/sites/slots@2023-12-01' = {
  parent: webApp
  name: 'staging'
  location: location
  properties: {
    serverFarmId: plan.id
    httpsOnly: true
    siteConfig: {
      netFrameworkVersion: 'v8.0'
      alwaysOn: true
    }
  }
}

parent: webApp face din staging un slot al aplicației principale. alwaysOn: true îl ține pornit, ca warm-up-ul să fie rapid.


🔗 În pipeline: deploy în slot, apoi swap

Job-ul de producție face acum doi pași – deployează în staging, apoi comută:

  deploy-production:
    runs-on: ubuntu-latest
    needs: build-test
    environment:
      name: production
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: app
          path: ./publish

      - name: Azure login
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

      - name: Deploy in slotul staging
        uses: azure/webapps-deploy@v3
        with:
          app-name: my-app-prod
          slot-name: staging
          package: ./publish

      - name: Swap staging in productie
        run: |
          az webapp deployment slot swap \
            --resource-group rg-myapp-prod \
            --name my-app-prod \
            --slot staging \
            --target-slot production

Noua versiune ajunge întâi în staging (unde se încălzește), iar pasul de swap o promovează în producție fără downtime. Combinat cu approval gate-ul din partea 2, ai și controlul: swap-ul se întâmplă doar după ce cineva a aprobat.


↩️ Rollback în câteva secunde

Bonusul mare: după swap, versiunea veche nu dispare – ajunge în slotul staging. Dacă observi o problemă în producție, faci swap din nou și te întorci instant la versiunea anterioară:

az webapp deployment slot swap \
  --resource-group rg-myapp-prod \
  --name my-app-prod \
  --slot staging \
  --target-slot production

Fără rebuild, fără redeploy, fără panică. Rollback-ul e tot un swap.


✅ Câteva reguli sănătoase

  • Plan Standard sau Premium – fără el nu ai sloturi.

  • Ține alwaysOn pe slotul de staging, ca warm-up-ul să fie rapid.

  • Marchează connection string-urile specifice mediului ca sticky (deployment slot setting).

  • Verifică sănătatea slotului înainte de swap – un health check pe staging îți spune dacă e gata.

  • După swap, nu șterge imediat versiunea din staging – e plasa ta de rollback.


Concluzie

Deployment slots transformă release-ul dintr-o întrerupere programată într-un non-eveniment: deployezi lângă producție, încălzești, comuți instant, iar dacă ceva e prost te întorci printr-un swap. Zero downtime, plus rollback în câteva secunde.

Ne-a mai rămas o piesă – și e cea la care am tot făcut trimitere. În toate exemplele, azure/login s-a autentificat fără nicio parolă. În partea 5, ultima din serie, vedem exact cum: Managed Identity și OIDC, ca în pipeline și în aplicație să nu mai existe niciun secret la vedere.