Bien le bonjour !
Justement je pensais à vous en me disant : mais je ne vais quand même pas les laisser avec le gâteau prêt à être mangé sans ajouter les fruits et la crème. Il est midi, j’ai faim.
Vous l’aurez compris, si vous êtes là c’est que vous avez suivi (et je vous en remercie) au moins mon tutoriel vous expliquant comment installer une application SSR Nuxt sous Firebase. Et si vous avez été attentifs j’ai, lors de ce tutoriel, supprimé le répertoire .git
afin de nous débarrasser de la trace des versions de fichiers.
Je vais maintenant vous proposer de remettre en place la gestion des sources ainsi que de l’intégration continue sous Gitlab et ce avec deux environnements : développement et production.
Si vous n’êtes pas encore familiarisés, je vous redirige vers cet article qui explique de manière simple et concise l’intérêt de mettre en place plusieurs environnements, leurs rôles et leurs spécificités.
Cela étant dit, allons-y !
Pré-requis
Ce tutoriel est la continuité du dernier. Je me baserai donc sur l’application obtenue à la fin de la partie 2.
Vous allez avoir besoin de Git.
Il vous faudra un compte Gitlab. Bien évidemment il est possible d’utiliser le CI/CD de votre choix mais il vous faudra adapter les instructions que je fournirai au système pour lequel vous opterez.
Il vous faudra avoir créé deux projets Firebase et récupérer leur ID pour les écrire dans le fichier .firebaserc
. L’un sera dédié au developpement, l’autre à la production.
Création du projet Gitlab
Juste créer un projet Gitlab portant le nom de votre application.
Initialisation
Je vous invite de vous rendre à la racine du projet nuxt-on-firebase/
et à lancer la commande suivante qui initialisera le traçage git :
git init
Sous VS Code vous devriez voir apparaitre la surbrillance verte propre à la detection de modifications dans le projet.
Vous êtes à présent sous la branche principale master.
Décidément pour le moment c’est pas la folie. On y vient on y vient.
Maintenant on va envoyer tout ce beau monde sous votre projet gitlab :
## Association au répertoire distant git remote add origin <lien de votre projet gitlab> ## Ajout de tout le répertoire local git add . ## Création du commit git commit -m "Commit initial, le SSR est en place" ## Et du coup on envoie tout sur le répertoire distant git push -u origin master
Et si vous allez sur votre projet, pouf il y a vos sources.
Récupération du token firebase
Vous avez du remarquer que pour déployer une application sous Firehost il nous faut l’associer à un projet sous la console. Souvenez vous :) Pour cela nous nous connections à Firebase via un firebase login
qui nous ouvrait un onglet de navigateur avec une interface bien pratique. Une fois la partie interface passée, hop on était loggués.
La question se pose maintenant : comment faire pour de l’intégration continue ?
Une fois le déploiement lancé dans le pipeline, l’ouverture d’une page web est impossible. Firebase a pensé à tout, nous allons utiliser un token de connexion généré ainsi :
firebase login:ci
Cette commande va vous donner un token de connexion que vous irez appliquer dans gitlab dans les variables d’environnement du repository.
Settings > CI/CD > Variables.
Le Fichier .gitlab-ci.yml
Pour commencer je vous invite à regarde un peu la documentation de Gitlab si vous n’êtes pas familiés de ce type de fichier.
Maintenant on va écrire le script de déploiement. Le fichier Yaml par défaut lu par gitlab lors d’un commit est le fichier .gitlab-ci.yml.
Créons le à la racine :
touch .gitlab-ci.yml
Et voici ce que l’on trouvera dedans :
image: andreysenov/firebase-tools stages: - build - deploy build: environment: test stage: build script: - npm run setup - npm run build except: - master deploy-dev: environment: test stage: deploy only: - master script: - npm run setup - firebase use develop --token $FIREBASE_TOKEN - firebase deploy -m "Deploying to test environment" --token $FIREBASE_TOKEN deploy-prod: environment: production stage: deploy only: - tags script: - npm run setup - firebase use production --token $FIREBASE_TOKEN - firebase deploy -m "Deploying to production environment" --token $FIREBASE_TOKEN
Nous utilisons déjà une image firebase afin d’avoir les commandes Firebase et Node de base.
-
Nous avons donc un job build qui s’éxécutera à chaque fois que vous pusherez quelque chose sur le repository Gitlab tant qu’il ne s’agit pas de la branche master.
-
Le job deploy-dev s’éxécutera lorsque vous mergerez vos travaux sur la branche master. Cela déclenchera donc un déploiement en environnement de développement.
-
Enfin, le job deploy-prod s’éxécutera au tag de la branche master. Cela vous permettra de gérer vos releases de production efficacement.
Dans chacun des scripts je dis à firebase d’utiliser l’ID du projet Firebase indiqué pour le développement ou la production. Ainsi il vous suffira de créer un autre projet Firebase via la Firebase Console et de modifier le fichier .firebaserc
avec les ID des projets vous servant d’environnement de dev ou de prod. De cette manière, il est possible d’ajouter une multitude d’environnements.
L’authentification firebase s’effectue via l’option --token
à laquelle on attribue la variable d’environnement Gitlab $FIREBASE_TOKEN
mise en place plus haut.
Allez, on commit tout ça :
## Ici on est sous le master git checkout -b continuous-integration git add .gitlab-ci.yml git commit -m "ajout du fichier de déploiement" git push --set-upstream origin continuous-integration
Il ne nous reste plus qu’à merge cette branche dans le master depuis gitlab.
Suite à cela, Gitlab lance un déploiement du master. Vous pouvez alors tagger le master. Le déploiement se fera sous le projet firebase lié à l’environnement de production.
Tout va bien dans le meilleur des mondes ! Vous avez mis en place de l’intégration continue ! Bravo.
Maintenant d’autres petites questions vont se poser.
Gestion des environnements
Ne vous rejouissez pas trop vite, Nuxt a tout de même ses petites manignances derrière notre dos.
Reprenons, nous sommes d’accord que si vous souhaitez une application tournant en dev et une en production il va vous falloir deux projets Firebase.
Il est à noter qu’il est tout de même possible sous Firebase d’avoir plusieurs applications sous un même projet. Elle partageront les ressources et auront chacunes leurs statistiques propres. Ce cas peut vous interesser mais ce n’est pas celui que je choisis ici car si on souhaite par la suite avoir une base de données Firestore par environnement, on aura besoin de deux projets distincts.
Bref qui dit deux projets dit deux configurations d’API différentes. Il nous faut donc tester si nous sommes en developpement ou en production.
Toi, au fond je t’ai entendu avec ton : "Nan mais il suffit d’utiliser NODE_ENV et voilà"
Eh non… Nuxt est, comme je vous le disais, un petit malin. La commande nuxt build
lancée lors de notre npm run build
écrase automatiquement NODE_ENV par “production”.
Donc il faut ruser. Et là je retrouve mon nuxtichou d’amour avec la propriété env dans le fichier nuxt.config.js
.
Tout simplement on va définir des variables d’environnement au build que l’on pourra par la suite réutiliser à notre guise.
Il va donc nous falloir créer une propriété indiquant l’environnement courant qui nous servira pour gérer des comportements différents de l’application en fonction de son environnement d’éxécution. Nous allons également créer les variables nécessaires à la configuration de l’API Firebase.
Et pour les récupérer on attribue donc la fameuse propriété env dans le fichier nuxt.config.js
:
env: { app_env: process.env.APP_ENV, FIREBASE_API_KEY: process.env.FIREBASE_API_KEY, FIREBASE_DATABASE_NAME: process.env.FIREBASE_DATABASE_NAME, FIREBASE_PROJECT_ID: process.env.FIREBASE_PROJECT_ID, FIREBASE_SENDER_ID: process.env.FIREBASE_SENDER_ID },
La question qui se pose maintenant c’est comment récupérer tout cela au build dépendament de l’environnement sachant que l’on doit considérer le démarrage en local ?
Je répondrai par : Dotenv + Gitlab !
Dotenv
Afin de gérer des variables d’environnement en local nous allons utiliser dotenv et plus spécifiquement le module fait pour Nuxt. Il s’agit d’un module permettant de charger les variables d’environnement du fichier .env
directement dans l’application. Cette attribution s’effectue au build de Nuxt.
## Ici nous sommes sous /src dans notre application. ## En effet on souhaite installer cette dépendance pour l'application Nuxt uniquement. npm install @nuxtjs/dotenv
Il nous faudra ensuite aller dans le fichier nuxt.config.js
et y rajouter le module dotenv :
buildModules: [ '@nuxtjs/dotenv' ],
Parlons maintenant de ce fameux fichier .env
. Avant de créer le fichier, bien s’assurer qu’il est présent dans votre .gitignore. On n’en veut pas dans la gestion de sources.
## Sous src toujours
touch .env
Dans le fichier vous y mettrez vos variables d’environnement comme suis:
APP_ENV=develop FIREBASE_API_KEY=votre_api_key_Firebase FIREBASE_DATABASE_NAME=votre_database_name_Firebase FIREBASE_PROJECT_ID=votre_project_id_Firebase FIREBASE_SENDER_ID=votre_sender_id_Firebase
J’ai jamais autant écrit Firebase de ma vie. Firebase.
Bien pour le local c’est bon. Vos variables d’environnment sont attribuées. Le fichier .env
n’est pas tracé et donc il faut trouver un autre moyen de les attribuer lorsque l’on déploie l’application.
Gitlab
Ce qu’il y a de bien avec le Gitlab CI c’est que l’on peut lui spécifier dans ses jobs des constantes utilisables au moment du build de l’application. Donc ce code FIREBASE_API_KEY: process.env.FIREBASE_API_KEY
(voir plus haut) fonctionnera autant en local qu’au déploiement en dev ou prod.
Donc déjà il faut ajouter les variables sous Settings > CI/CD > Variables.
On ajoute donc ces 8 variables :
- FIREBASE_API_KEY_DEV
- FIREBASE_DATABASE_NAME_DEV
- FIREBASE_PROJECT_ID_DEV
- FIREBASE_SENDER_ID_DEV
- FIREBASE_API_KEY_PROD
- FIREBASE_DATABASE_NAME_PROD
- FIREBASE_PROJECT_ID_PROD
- FIREBASE_SENDER_ID_PROD
Je vous laisse attribuer les bonnes valeurs avec celles de vos projets Firebase.
Vous pouvez modifier votre fichier .gitlab-ci.yml
qui ressemblera à ceci :
image: andreysenov/firebase-tools stages: - build - deploy build: environment: test stage: build script: - npm run setup - npm run build:dev except: - master deploy-dev: environment: test stage: deploy only: - master variables: APP_ENV: $APP_ENV_DEV FIREBASE_API_KEY: $FIREBASE_API_KEY_DEV FIREBASE_DATABASE_NAME: $FIREBASE_DATABASE_NAME_DEV FIREBASE_PROJECT_ID: $FIREBASE_PROJECT_ID_DEV FIREBASE_SENDER_ID: $FIREBASE_SENDER_ID_DEV script: - npm run setup - firebase use develop --token $FIREBASE_TOKEN - firebase deploy -m "Deploying to test environment" --token $FIREBASE_TOKEN deploy-prod: environment: production stage: deploy only: - tags variables: APP_ENV: $APP_ENV_PROD FIREBASE_API_KEY: $FIREBASE_API_KEY_PROD FIREBASE_DATABASE_NAME: $FIREBASE_DATABASE_NAME_PROD FIREBASE_PROJECT_ID: $FIREBASE_PROJECT_ID_PROD FIREBASE_SENDER_ID: $FIREBASE_SENDER_ID_PROD script: - npm run setup - firebase use production --token $FIREBASE_TOKEN - firebase deploy -m "Deploying to production environment" --token $FIREBASE_TOKEN
On notera bien les propriétés variables
qui ont été rajoutées avec les clefs précédemment configurées sous Gitlab.
Pour le déploiement, tout est en place.
Le plugin d’initialisation Firebase
Cet article commence à être vraiment long. C’est le dernier chapitre (promis).
Maintenant que vous disposez de vos projets firebase de dev et de prod et de vos variables d’environnement spécifiques on peut mettre en place ce qu’il faut pour pouvoir utiliser firebase au sein de l’application.
Dans le répertoire plugins de Nuxt, on va créer un fichier nommé fireapp.js
cd src/plugins && touch fireapp.js ## On va avoir besoin du package firebase ## Ne pas oublier de retourner sous src cd .. && npm install firebase
Dans ce fichier, on trouvera donc :
import firebase from 'firebase' if(!firebase.apps.length) { //On utilise nos fameuses variables d'environnement const config = { apiKey: process.env.FIREBASE_API_KEY, authDomain: `${process.env.FIREBASE_PROJECT_ID}.firebaseapp.com`, databaseURL: `https://${process.env.FIREBASE_DATABASE_NAME}.firebaseio.com`, projectId: process.env.FIREBASE_PROJECT_ID, storageBucket: `${process.env.FIREBASE_PROJECT_ID}.appspot.com`, messagingSenderId: process.env.FIREBASE_SENDER_ID } //Initialisation de firebase firebase.initializeApp(config) } // On stocke les instances const firebaseApp = firebase.app() const fireDb = firebase.firestore() //Et on les rends disponible à qui en aura besoin dans l'application export { firebaseApp } export { fireDb }
N’oubliez pas d’ajouter le fichier aux plugins Nuxt dans le fichier nuxt.config.js
.
Conclusion
Et voilà !
Nous avons mis en place de l’intégration continue pour notre application ainsi que la disponilité de l’API Firebase (application et base de données en temps réel) pour deux environnements d’éxécution.
Si jamais vous avez besoin d’idées pour la gestion utilisateur FireAuth ou la mise en place d’une base de données Firebase (avec son ORM Firestorm), cela me fera plaisir de vous présenter différentes solutions relatives à ces sujets. N’hésitez donc pas à revenir vers moi.
Je vous remercie d’avoir suivi ce tutoriel et vous dis à très bientot.
Happy coding !
Bien à vous,
Pophip.