Dans cet article je partage avec vous comment je déploie ce site (loopbin.dev) gratuitement avec des pipelines CI/CD.
Comment ça marche ? Tout repose sur un couple d'outils : GitHub Actions pour l'automatisation et Firebase Hosting pour l'hébergement.
Voici une vue globale de l'architecture que j'ai mise en place :

1. Firebase Hosting : le multi-site à budget zéro
La plupart des hébergeurs gratuits limitent les projets à un seul site par compte. Chez Firebase (Google Cloud), il y a une option super pratique : le multi-site. On peut créer plusieurs sites d'hébergement indépendants dans le même projet.
Dans mon cas, j'ai configuré deux sites distincts :
loopbin-luna(Staging, accessible surhttps://luna.loopbin.dev)loopbin(Production, accessible surhttps://loopbin.dev)
Le fichier firebase.json
Rien de plus simple que de déclarer mes deux cibles dans mon fichier firebase.json :
{
"hosting": [
{
"site": "loopbin-luna",
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"redirects": [
{
"source": "/tutos",
"destination": "/articles",
"type": 301
},
...
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
},
{
"site": "loopbin",
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"redirects": [
{
"source": "/tutos",
"destination": "/articles",
"type": 301
},
...
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
]
}
Le détail technique qui fait plaisir : redirections au niveau du CDN edge
Vous avez vu la clé redirects ? Si on gère les redirections des anciennes pages (/tutos et /posts vers /articles) dans le code de notre app, le navigateur doit charger les scripts, initialiser le routeur et rediriger. C'est lent et mauvais pour le SEO.
En plaçant ces règles dans firebase.json, Firebase Hosting gère la redirection directement au niveau du CDN edge. L'utilisateur reçoit immédiatement un statut HTTP 301 Moved Permanently sans charger une seule ligne de JS côté client. C'est instantané.
Je fais ces redirects pour garder une certaine consistance entre le SEO de mon ancien site et cette nouvelle version.
2. Sécurisation de la liaison par compte de service GCP
Faire causer GitHub Actions avec Google Cloud demande un peu de sécurité. On oublie les identifiants persos ou les vieux jetons Firebase.
Toute la sécurité repose sur un compte de service GCP dédié aux déploiements, stocké proprement dans mes GitHub Secrets sous le nom de FIREBASE_SERVICE_ACCOUNT_LOOPBIN.
Pour respecter le principe de moindre privilège, ce compte n'a que deux rôles IAM :
API Keys Viewer(pour lire les configurations de base nécessaires)Firebase Hosting Admin(pour uploader les fichiers statiques et publier les releases)
Si jamais votre secret GitHub fuite, l'attaquant ne pourra pas toucher à vos bases de données ni lancer de VM sur votre compte GCP. C'est une sécurité en plus.
3. Les workflows GitHub Actions sous le capot
Pour piloter le cycle de vie de notre code, j'ai mis en place une stratégie Git standard à deux branches :
- Un push sur la branche
maindéploie automatiquement sur Staging (loopbin-luna). - Un push ou un merge sur la branche
livedéploie directement en Production (loopbin).
Le workflow d'intégration (.github/workflows/firebase-deploy-integration.yml)
name: Deploy to Staging
on:
push:
branches: [main]
env:
IN_PRODUCTION: false
NUXT_PUBLIC_SITE_URL: https://luna.loopbin.dev
jobs:
build_and_deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v6
with:
node-version: "22.x"
- run: yarn install && yarn generate
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_LOOPBIN }}
channelId: live
projectId: loopbin
target: loopbin-luna
Le workflow de production (.github/workflows/firebase-deploy-live.yml)
name: Deploy to Live
on:
push:
branches: [live]
env:
IN_PRODUCTION: true
NUXT_PUBLIC_SITE_URL: https://loopbin.dev
jobs:
build_and_deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v6
with:
node-version: "22.x"
- run: yarn install && yarn generate
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_LOOPBIN }}
channelId: live
projectId: loopbin
target: loopbin
Comment s'opère la magie de l'action GitHub ?
L'action officielle FirebaseExtended/action-hosting-deploy@v0 s'occupe de tout :
firebaseServiceAccount: Notre secret contenant les credentials GCP chiffrés.channelId: live: On déploie directement sur le canal principal (live) du site cible pour rendre les modifs immédiatement publiques.target: C'est ici que réside le secret du multi-site. Ce paramètre doit correspondre exactement à la clésitedéclarée dansfirebase.json(loopbin-lunaouloopbin).
4. Dompter l'indexation SEO de l'environnement Staging
Avoir un environnement de Staging pour valider visuellement un rendu ou tester des polices de caractères, c'est quand même bien plus pratique. Mais cela introduit un risque majeur : le duplicate content (contenu dupliqué). Si Google indexe luna.loopbin.dev, il pénalisera l'indexation de votre vrai domaine loopbin.dev.
Pour éviter ça, on peut demander à Firebase Hosting d'envoyer un en-tête HTTP spécifique sur la staging.
Toute la magie s'opère à ce niveau : on rajoute simplement une règle headers dans la configuration du site loopbin-luna dans notre firebase.json :
{
"site": "loopbin-luna",
"public": "dist",
"headers": [
{
"source": "**",
"headers": [
{
"key": "X-Robots-Tag",
"value": "noindex, nofollow"
}
]
}
]
}
Cet en-tête X-Robots-Tag bloque l'indexation de la Staging par Google et Bing directement à la requête HTTP, sans toucher à la Production. C'est propre, fiable et géré par le CDN.
5. Le bilan technique
En combinant Firebase Hosting et GitHub Actions, j'ai réussi à obtenir une CI/CD plus robuste, plus sûre et bien plus rapide.
- Coût d'exploitation : Gratuit (hors domaine) bien sur.
- Sécurité : Maximale (pas de base de données publique, accès restreint via IAM GCP).
- Expérience de dev : Un simple push et le site est en ligne en moins d'une minute.
C'est de loin le meilleur moyen que j'ai trouvé pour héberger et déployer mes projets sans friction, et c'est une architecture solide que je vous recommande vivement d'adopter.