Skip to content

Commit

Permalink
[Tech] Injection des variables d'env au runtime (#2715)
Browse files Browse the repository at this point in the history
## Linked issues

- Resolve #2714
- `import-meta-env` demande de ne pas utiliser un prefixe en `VITE_`
pour éviter un clash avec Vite

----

- [ ] Tests E2E (Cypress)
  • Loading branch information
louptheron committed Nov 23, 2023
2 parents c561ed3 + 27b56e0 commit a978200
Show file tree
Hide file tree
Showing 21 changed files with 666 additions and 109 deletions.
67 changes: 67 additions & 0 deletions adrs/0001-frontend-runtime-env-var-injection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Injection au runtime des variable d'env dans le frontend

Date: 22/11/2023

## Statut

Résolu

## Contexte

Lors du passage de `CRA` à `Vite`, on a perdu la possibilité d'injecter des variables d'environnements au frontend au runtime.

Pour respecter les 12-factor app et avoir plus d'agilité dans la gestion des variables d'env, nous allons rajouter cette feature.

Trois options :
1. Utiliser `import-meta-env` qui injecte dans l'`ENTRYPOINT` docker du backend les variables
2. Ajouter un controlleur `Index` dans le backend, qui retourne le contenu de `index.html` lans lequel il injecte des balises `meta` qui contiennent les variables
3. Utiliser le script `env.sh`, qui injecte dans l'`ENTRYPOINT` docker du backend les variables dans le frontend avec le CLI `sed`

### Utiliser `import-meta-env`

Cette méthode utilise un fichier `.env.template` qui défini les variables à injecter dynamiquement et gére le développement `compile-time` et la production `runtime`.

Un fichier `.env.example` permet de filtrer les variables à injecter dans le frontend.

Il faut rajouter dans l'image docker finale le script `import-meta-env` (préalablement packagé avec `npx pkg`) pour effectuer l'injection dans le fichier `index.html`.

Cette méthode nécessite de rajouter une nouvelle lib dans notre étape de build.

### Ajouter un controlleur `Index` dans le backend

Cette méthode demande:
- D'ajouter les balises `meta` dans le payload retourné sur `/`. (i.e `<meta name="MAPBOX_KEY" content="${System.getenv("MAPBOX_KEY")}" />`)
- De rendre les nom d'assets déterministes (i.e `/assets/index.js`)
- Cela nous oblige à avoir la gestion du cache dans ce controlleur, avec par exemple un `hash=randomString` généré au démarrage
- L'objet JS généré à la volée avec les balises `meta` ne sera pas typé
- Il faut modifier l'env de dev pour avoir
- un build `Vite` "watché" au lieu d'un run de dev watché par défaut
- un `.setCacheControl()` dans le backend pour éviter le caching en dev

### Utiliser le script `env.sh`

Ce script utilise un object `env` pour stocker les variables (i.e):
```
self.env = {
REACT_APP_MONITORENV_URL: '__REACT_APP_MONITORENV_URL__'
}
```

Et un script au démarrage de l'image docker avec `ENTRYPOINT ["/home/monitorfish/env.sh"]` (i.e):
```
sed -i 's#__REACT_APP_MONITORENV_URL__#'"$REACT_APP_MONITORENV_URL"'#g' /home/monitorfish/public/env.js
```

- Cette méthode construit un objet `env` non-typé

## Décision

Nous rajoutons une injection au runtime des dépendances avec `import-meta-env`.

Cet outil permet:
1) De ne pas dupliquer la spécification des variables
2) Ne change pas la façon de gérer les env var de `Vite`: `import.meta.env`

## Conséquences

Nos devons **obligatoirement** spécifier toutes les variables d'env dans le docker-compose lors du run de l'application `backend` (qui contient le frontend).
12 changes: 12 additions & 0 deletions frontend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FRONTEND_GEOSERVER_LOCAL_URL=
FRONTEND_GEOSERVER_REMOTE_URL=
FRONTEND_IS_DEV_ENV=
FRONTEND_MAPBOX_KEY=
FRONTEND_MONITORENV_URL=
FRONTEND_OIDC_AUTHORITY=
FRONTEND_OIDC_CLIENT_ID=
FRONTEND_OIDC_ENABLED=
FRONTEND_OIDC_REDIRECT_URI=
FRONTEND_SENTRY_DSN=
FRONTEND_SHOM_KEY=
VITE_SMALL_CHAT_SNIPPET=
12 changes: 12 additions & 0 deletions frontend/cypress/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ services:
- SENTRY_DSN=
- MONITORENV_URL=http://geoserver-monitorenv-stubs:8080
- MONITORFISH_API_PROTECTED_API_KEY=APIKEY
- FRONTEND_GEOSERVER_LOCAL_URL=http://0.0.0.0:8081
- FRONTEND_GEOSERVER_REMOTE_URL=http://0.0.0.0:8081
- FRONTEND_IS_DEV_ENV=true
- FRONTEND_MAPBOX_KEY=pk.eyJ1IjoibW9uaXRvcmZpc2giLCJhIjoiY2tsdHJ6dHhhMGZ0eDJ2bjhtZmJlOHJmZiJ9.bdi1cO-cUcZKXdkEkqAoZQ
- FRONTEND_MONITORENV_URL=http://0.0.0.0:8081
- FRONTEND_OIDC_AUTHORITY=https://authentification.recette.din.developpement-durable.gouv.fr/authSAML/oidc/monitorfish
- FRONTEND_OIDC_CLIENT_ID=monitorfish
- FRONTEND_OIDC_ENABLED=false
- FRONTEND_OIDC_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr
- FRONTEND_SENTRY_DSN=https://a5f3272efa794bb9ada2ffea90f2fec5@sentry.incubateur.net/8
- FRONTEND_SHOM_KEY=rg8ele7cft4ujkwjspsmtwas
- VITE_SMALL_CHAT_SNIPPET=
ports:
- 8880:8880
- 8000:8000
Expand Down
52 changes: 3 additions & 49 deletions frontend/cypress/support/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,62 +114,16 @@ beforeEach(() => {
statusCode: 200
})

// DEV :: VITE_GEOSERVER_LOCAL_URL
// PROD :: VITE_GEOSERVER_LOCAL_URL
cy.intercept({ url: /^https?:\/\/10\.56\.205\.25:808(1|2)\/.*/ }, req => {
req.redirect(
req.url
.replace('http://10.56.205.25:8081', 'http://0.0.0.0:8081')
.replace('http://10.56.205.25:8082', 'http://0.0.0.0:8081')
.replace('https://10.56.205.25:8081', 'http://0.0.0.0:8081')
.replace('https://10.56.205.25:8082', 'http://0.0.0.0:8081')
)
})

// DEV :: VITE_GEOSERVER_REMOTE_URL
cy.intercept({ url: /^https?:\/\/monitorfish-test\.csam\.e2\.rie\.gouv\.fr\/.*/ }, req => {
req.redirect(
req.url
.replace('http://monitorfish-test.csam.e2.rie.gouv.fr', 'http://0.0.0.0:8081')
.replace('https://monitorfish-test.csam.e2.rie.gouv.fr', 'http://0.0.0.0:8081')
)
})
// PROD :: VITE_GEOSERVER_REMOTE_URL
cy.intercept({ url: /^https?:\/\/monitorfish\.din\.developpement-durable\.gouv\.fr\/.*/ }, req => {
req.redirect(
req.url
.replace('http://monitorfish.din.developpement-durable.gouv.fr', 'http://0.0.0.0:8081')
.replace('https://monitorfish.din.developpement-durable.gouv.fr', 'http://0.0.0.0:8081')
)
})

// DEV :: VITE_MONITORENV_URL
cy.intercept({ url: /^https?:\/\/monitorenv\.kadata\.fr\/.*/ }, req => {
req.redirect(
req.url
.replace('http://monitorenv.kadata.fr', 'http://0.0.0.0:8081')
.replace('http://monitorenv.kadata.fr', 'https://0.0.0.0:8081')
)
})
// PROD :: VITE_MONITORENV_URL
cy.intercept({ url: /^https?:\/\/monitorenv\.din\.developpement-durable\.gouv\.fr\/.*/ }, req => {
req.redirect(
req.url
.replace('http://monitorenv.din.developpement-durable.gouv.fr', 'http://0.0.0.0:8081')
.replace('https://monitorenv.din.developpement-durable.gouv.fr', 'http://0.0.0.0:8081')
)
})

// DEV :: VITE_SENTRY_DSN
// PROD :: VITE_SENTRY_DSN
// DEV :: FRONTEND_SENTRY_DSN
// PROD :: FRONTEND_SENTRY_DSN
cy.intercept(
{ url: /^https:\/\/a5f3272efa794bb9ada2ffea90f2fec5@sentry\.incubateur\.net\/.*/ },
{
statusCode: 200
}
)

// PROD :: VITE_SMALL_CHAT_SNIPPET
// PROD :: FRONTEND_SMALL_CHAT_SNIPPET
cy.intercept(
{ url: /^https:\/\/embed\.small\.chat\/.*/ },
{
Expand Down
9 changes: 9 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,16 @@
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>

<!-- We need to use a VITE_ env var to replace the HTML index file -->
<!-- see: https://vitejs.dev/guide/env-and-mode.html#html-env-replacement -->
%VITE_SMALL_CHAT_SNIPPET%

<!-- This script will be used by the `import-meta-env` library to inject -->
<!-- runtime environment variables when running in production -->
<!-- see: https://import-meta-env.org/guide/getting-started/introduction.html -->
<script>
globalThis.import_meta_env = JSON.parse('"import_meta_env_placeholder"')
</script>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
Loading

0 comments on commit a978200

Please sign in to comment.