Salta al contenuto principale

3 - Firebase Hosting + GitHub Actions: Deploy Automatico

Come configurare deploy automatico su Firebase Hosting con GitHub Actions: preview channels, staging/production environments e rollback.

Cosa ne pensi di questo articolo?

3 - Firebase Hosting + GitHub Actions: Deploy Automatico
DevOps FrontendFoto:Bibek ghoshPexels

In Breve

Come configurare deploy automatico su Firebase Hosting con GitHub Actions: preview channels, staging/production environments e rollback.

Introduzione: Deploy Automatico con Firebase e GitHub Actions

Il deploy manuale e il nemico della produttività e dell'affidabilità. Ogni volta che esegui firebase deploy dal tuo terminale, introduci il rischio di errori umani: dimenticare di fare il build, deployare dal branch sbagliato, o saltare i test. In questo articolo costruiremo un sistema di deploy completamente automatizzato usando Firebase Hosting e GitHub Actions.

Firebase Hosting e una piattaforma di hosting per applicazioni web statiche e dinamiche che offre CDN globale, certificati SSL automatici, preview channel per le Pull Request, e rollback istantaneo. Combinato con GitHub Actions, crea un flusso di lavoro dove ogni push a main viene automaticamente deployato in produzione, e ogni Pull Request genera un'anteprima accessibile via URL.

Cosa Imparerai in Questo Articolo

  • Come configurare Firebase CLI e inizializzare un progetto
  • La struttura del file firebase.json e le sue opzioni
  • Come creare preview channel automatici per le Pull Request
  • Il workflow completo per il deploy in produzione
  • Strategie di rollback per gestire errori in produzione
  • Come configurare un dominio personalizzato
  • Header di caching e regole di redirect
  • Confronto tra Firebase Hosting e le alternative

1. Setup di Firebase CLI

Il primo passo e installare e configurare la Firebase CLI. Questa CLI e lo strumento principale per interagire con Firebase dal terminale e dalle pipeline CI/CD.


# Installare Firebase CLI globalmente
npm install -g firebase-tools

# Verificare l'installazione
firebase --version

# Login (apre il browser per l'autenticazione)
firebase login

# Per ambienti CI/CD, usare un token
firebase login:ci
# Questo genera un token da salvare come segreto GitHub

# Inizializzare Firebase nel progetto
firebase init hosting
      

Durante l'inizializzazione, Firebase fara alcune domande sulla configurazione. Ecco le risposte consigliate per un progetto Angular:

  • Public directory: dist/my-app/browser (la cartella di output della build Angular)
  • Configure as single-page app: Si (riscrive tutti gli URL a index.html)
  • Set up automatic builds with GitHub: Si (configura automaticamente i workflow)
  • Overwrite index.html: No (usiamo il nostro)

2. Configurazione firebase.json

Il file firebase.json e il cuore della configurazione di Firebase Hosting. Ecco una configurazione completa e ottimizzata per un progetto Angular:


{
  "hosting": {
    "public": "dist/my-app/browser",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ],
    "headers": [
      {
        "source": "**/*.@(js|css)",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "public, max-age=31536000, immutable"
          }
        ]
      },
      {
        "source": "**/*.@(jpg|jpeg|gif|png|svg|webp|ico)",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "public, max-age=86400"
          }
        ]
      },
      {
        "source": "**/*.@(woff|woff2|ttf|eot)",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "public, max-age=31536000, immutable"
          }
        ]
      },
      {
        "source": "**",
        "headers": [
          {
            "key": "X-Frame-Options",
            "value": "SAMEORIGIN"
          },
          {
            "key": "X-Content-Type-Options",
            "value": "nosniff"
          },
          {
            "key": "X-XSS-Protection",
            "value": "1; mode=block"
          },
          {
            "key": "Referrer-Policy",
            "value": "strict-origin-when-cross-origin"
          }
        ]
      }
    ]
  }
}
      

Sezioni Chiave di firebase.json

Sezione Scopo Dettaglio
public Directory dei file da servire Deve corrispondere all'output della build Angular
rewrites Routing SPA Tutte le richieste vengono reindirizzate a index.html
headers Caching e sicurezza Cache aggressiva per asset con hash, header di sicurezza globali
ignore File da escludere File di configurazione e directory nascoste

Regole di Redirect

Firebase Hosting supporta redirect HTTP per gestire URL legacy o forzare HTTPS:


{
  "hosting": {
    "redirects": [
      {
        "source": "/old-blog/:slug",
        "destination": "/blog/:slug",
        "type": 301
      },
      {
        "source": "/api/**",
        "destination": "https://api.example.com/v1/:splat",
        "type": 302
      },
      {
        "source": "/docs",
        "destination": "https://docs.example.com",
        "type": 301
      }
    ]
  }
}
      

3. Preview Channel per le Pull Request

I preview channel sono una delle funzionalità più potenti di Firebase Hosting. Ogni Pull Request ottiene automaticamente un URL unico dove e possibile visualizzare le modifiche prima del merge. Ecco il workflow completo:


# .github/workflows/firebase-preview.yml
name: Firebase Preview Deploy

on:
  pull_request:
    branches: [main]

jobs:
  build-and-preview:
    name: Build and Deploy Preview
    runs-on: ubuntu-latest
    permissions:
      checks: write
      pull-requests: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: npx ng test --watch=false --browsers=ChromeHeadless

      - name: Build application
        run: npx ng build --configuration=production

      - name: Deploy to Firebase Preview Channel
        uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: ${{ secrets.GITHUB_TOKEN }}
          firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
          projectId: my-angular-project
          expires: 7d
      

Dopo il deploy, l'action aggiunge automaticamente un commento alla Pull Request con l'URL del preview. Il parametro expires: 7d configura la scadenza automatica del preview channel dopo 7 giorni.

Come Ottenere il Firebase Service Account

  1. Vai alla Console Firebase
  2. Seleziona il progetto > Impostazioni progetto > Account di servizio
  3. Clicca su "Genera nuova chiave privata"
  4. Scarica il file JSON
  5. Copia il contenuto e aggiungilo come segreto GitHub con nome FIREBASE_SERVICE_ACCOUNT

4. Workflow di Deploy in Produzione

Il workflow di produzione viene eseguito solo sui push al branch main e include tutti i controlli di qualità prima del deploy:


# .github/workflows/firebase-production.yml
name: Firebase Production Deploy

on:
  push:
    branches: [main]

concurrency:
  group: production-deploy
  cancel-in-progress: false

jobs:
  test:
    name: Run Tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - run: npx ng lint
      - run: npx ng test --watch=false --browsers=ChromeHeadless

  build:
    name: Build Application
    runs-on: ubuntu-latest
    needs: test
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - run: npx ng build --configuration=production
      - uses: actions/upload-artifact@v4
        with:
          name: production-build
          path: dist/
          retention-days: 1

  deploy:
    name: Deploy to Production
    runs-on: ubuntu-latest
    needs: build
    environment: production
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          name: production-build
          path: dist/

      - name: Deploy to Firebase Hosting
        uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: ${{ secrets.GITHUB_TOKEN }}
          firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
          channelId: live
          projectId: my-angular-project
      

Concurrency per Deploy in Produzione

Nota l'impostazione cancel-in-progress: false per il deploy in produzione. A differenza del CI dove possiamo cancellare build precedenti, per il deploy in produzione e meglio completare il deploy in corso prima di iniziarne uno nuovo, per evitare stati inconsistenti.

5. Strategia di Rollback

Nonostante test e review, a volte un deploy in produzione introduce problemi. Firebase Hosting offre diverse strategie per il rollback:

Rollback dalla Console Firebase

La Console Firebase mantiene la cronologia dei deploy. Per fare rollback a una versione precedente, vai su Hosting > Release history e clicca su "Rollback" accanto alla versione desiderata. Questo processo e istantaneo perchè Firebase mantiene tutti i file delle release precedenti sulla CDN.

Rollback via CLI


# Elencare le release recenti
firebase hosting:releases:list --limit 10

# Fare rollback a una release specifica
firebase hosting:rollback --release RELEASE_ID

# Alternativa: clone di una release precedente
firebase hosting:clone SOURCE_SITE:SOURCE_CHANNEL TARGET_SITE:live
      

Rollback Automatico via GitHub Actions


# .github/workflows/rollback.yml
name: Emergency Rollback

on:
  workflow_dispatch:
    inputs:
      commit-sha:
        description: 'Commit SHA to rollback to'
        required: true
        type: string
      reason:
        description: 'Reason for rollback'
        required: true
        type: string

jobs:
  rollback:
    name: Rollback to Previous Version
    runs-on: ubuntu-latest
    environment: production
    steps:
      - name: Checkout specific commit
        uses: actions/checkout@v4
        with:
          ref: ${{ inputs.commit-sha }}

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci
      - run: npx ng build --configuration=production

      - name: Deploy rollback version
        uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: ${{ secrets.GITHUB_TOKEN }}
          firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
          channelId: live
          projectId: my-angular-project

      - name: Notify team
        run: |
          echo "Rollback completed"
          echo "Commit: ${{ inputs.commit-sha }}"
          echo "Reason: ${{ inputs.reason }}"
      

6. Configurazione Dominio Personalizzato

Firebase Hosting supporta domini personalizzati con certificato SSL gratuito. Il processo di configurazione richiede la verifica della proprietà del dominio tramite record DNS.

Passi per la Configurazione

  1. Vai alla Console Firebase > Hosting > "Add custom domain"
  2. Inserisci il tuo dominio (es. example.com)
  3. Firebase fornira i record DNS da configurare nel tuo registrar
  4. Aggiungi i record TXT per la verifica e i record A per il routing
  5. Attendi la propagazione DNS (fino a 48 ore, tipicamente 1-4 ore)
  6. Firebase emettera automaticamente un certificato SSL

Record DNS da configurare:

# Verifica proprietà
TXT  @  firebase-hosting-verification=xxxxxxxxxxxxx

# Routing al CDN Firebase
A    @  151.101.1.195
A    @  151.101.65.195

# Sottodominio www (opzionale)
CNAME  www  my-project.web.app
      

7. Header di Caching Ottimizzati

Una configurazione di caching corretta e fondamentale per le prestazioni. Angular genera file con hash nel nome (es. main.abc123.js), che possono essere memorizzati in cache per un anno intero. Il file index.html invece non deve mai essere memorizzato in cache, perchè contiene i riferimenti ai file con hash:


{
  "hosting": {
    "headers": [
      {
        "source": "/index.html",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "no-cache, no-store, must-revalidate"
          }
        ]
      },
      {
        "source": "ngsw.json",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "no-cache"
          }
        ]
      },
      {
        "source": "**/*.@(js|css)",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "public, max-age=31536000, immutable"
          }
        ]
      },
      {
        "source": "**/*.@(jpg|jpeg|png|gif|svg|webp|avif|ico)",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "public, max-age=604800"
          }
        ]
      },
      {
        "source": "**/*.@(woff|woff2)",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "public, max-age=31536000, immutable"
          }
        ]
      }
    ]
  }
}
      

8. Confronto con le Alternative

Firebase Hosting non e l'unica opzione per il deploy di applicazioni Angular. Ecco un confronto con le alternative più popolari:

Firebase Hosting vs Alternative

Caratteristica Firebase Vercel Netlify AWS S3 + CloudFront
Setup Semplice Molto semplice Molto semplice Complesso
SSL gratuito Si Si Si Si (ACM)
CDN globale Si Si Si Si
Preview deploy Si Si (automatico) Si (automatico) Manuale
Rollback Istantaneo Istantaneo Istantaneo Manuale
Piano gratuito 10 GB storage, 360 MB/day transfer 100 GB bandwidth 100 GB bandwidth Pay-as-you-go
SSR Support Si (Cloud Functions) Si (nativo) Si (Functions) Si (Lambda@Edge)

9. Testing del Deploy in Locale

Prima di configurare il deploy automatico, e utile testare la configurazione Firebase in locale:


# Build dell'applicazione
npm run build

# Testare Firebase Hosting in locale
firebase emulators:start --only hosting

# Il sito sarà disponibile su http://localhost:5000
# Questo simula esattamente il comportamento di Firebase Hosting:
# - Rewrites SPA
# - Headers personalizzati
# - Redirect rules
# - Clean URLs

# Alternativa: serve direttamente la directory di build
firebase serve --only hosting
      

Checklist Pre-Deploy

  • La build di produzione viene generata senza errori
  • I test passano tutti
  • Il file firebase.json punta alla directory corretta
  • Gli header di caching sono configurati correttamente
  • I redirect per URL legacy sono in posizione
  • L'emulatore locale mostra il sito correttamente
  • Il service account Firebase e configurato come segreto GitHub
  • Le branch protection rules sono attive

Conclusione

In questo articolo abbiamo costruito un sistema di deploy completamente automatizzato con Firebase Hosting e GitHub Actions. Abbiamo configurato preview channel per le Pull Request, workflow di produzione con controlli di qualità, strategie di rollback per gestire emergenze, e ottimizzato la configurazione di caching e sicurezza.

Il vantaggio principale di questo approccio e la fiducia: una volta configurato, ogni modifica che passa la review e i test viene automaticamente deployata, senza intervento manuale e senza possibilità di errori. E se qualcosa va storto, il rollback e a portata di click.

Nel prossimo articolo affronteremo un tema cruciale per la sicurezza: la gestione dei segreti nelle pipeline CI/CD, esplorando come proteggere API key, token di servizio e credenziali durante il processo di build e deploy.

Domande frequenti

Come posso evitare errori umani nel processo di deploy manuale?

Utilizzando un sistema di deploy completamente automatizzato come quello descritto in questo articolo, che combina Firebase Hosting e GitHub Actions.

Qual è il vantaggio principale di utilizzare Firebase Hosting per il deploy delle applicazioni web statiche e dinamiche?

Il vantaggio principale è la possibilità di avere una piattaforma di hosting con CDN globale, certificati SSL automatici, preview channel per le Pull Request e rollback istantaneo.

Come posso configurare il preview channel per le Pull Request in Firebase Hosting?

Per configurare il preview channel è necessario utilizzare GitHub Actions e specificare la configurazione del preview channel nel file .yml della pipeline.

Quali sono le strategie di rollback disponibili in Firebase Hosting?

Le strategie di rollback disponibili in Firebase Hosting includono il rollback dalla Console Firebase, il rollback via CLI e il rollback automatico via GitHub Actions.

Prova Questi Strumenti

Strumenti gratuiti correlati a questo argomento.

Commenti

Caricamento commenti...

Accedi per commentare

Discuti questo articolo nella community

Unisciti al gruppo Telegram per discutere con altri sviluppatori, fare domande e condividere le tue esperienze.

Ti è piaciuto questo articolo?

Esplora altri contenuti sul blog o scopri i miei progetti