Produire la clé de chiffrement au premier démarrage
Le déploiement restait bloqué sur ENCRYPTION_KEY. J'ai tenu trop longtemps la position « pas de valeur par défaut », en confondant deux choses : refuser une clé livrée avec l'image — ce qui reste juste, une clé publiée dans un dépôt ne protège rien — et exiger qu'un humain en fabrique une avant tout démarrage. Une variable d'environnement n'est d'ailleurs pas un bon coffre : elle s'affiche dans `docker inspect` et dans l'interface de gestion. Un fichier produit au démarrage, dans un volume distinct de la base et des documents, n'est pas moins protégé — et une sauvegarde de l'un n'emporte plus la clé de l'autre. Le point d'entrée la produit donc si elle manque, l'écrit en 0600, et l'affiche une fois dans les journaux avec ce qu'il faut en faire. Une clé fournie explicitement l'emporte toujours : un déploiement qui gère ses secrets ailleurs ne doit pas être contrarié. La pile démarre désormais sans aucune variable. Éprouvé sur le script lui-même : première exécution, clé de 32 octets produite et annoncée ; deuxième, reprise en silence depuis le fichier ; avec une clé fournie, le fichier reste intact. Corrigé au passage, révélé par un échec transitoire du test : une écriture disque impossible — volume plein, droits, montage absent — remontait en exception non traitée. L'écran restait muet, la pièce n'était pas déposée et rien ne le disait. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cr9dkEHwbDgkWPnyGj1Rjv
This commit is contained in:
6 files changed
+91
-19
No files matched your search
@@ -49,12 +49,11 @@ devinent pas.
|
||||
### Avec Docker
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# ENCRYPTION_KEY est la seule variable sans valeur par défaut :
|
||||
echo "ENCRYPTION_KEY=$(openssl rand -base64 32)" >> .env
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
Aucune variable n'est requise. La clé de chiffrement est **produite au premier démarrage** et affichée une fois dans les journaux — notez-la, elle vit dans un volume distinct de la base et des documents.
|
||||
|
||||
L'application écoute sur <http://localhost:9317> — port peu courant à dessein, le service étant censé passer par un reverse-proxy. Les migrations s'appliquent au démarrage du conteneur.
|
||||
|
||||
La pile attend un réseau externe nommé `nginx_default`, celui du reverse-proxy. S'il n'existe pas encore :
|
||||
@@ -67,15 +66,13 @@ Seule l'application y est attachée. La base reste sur le réseau privé de la p
|
||||
|
||||
### Avec Portainer
|
||||
|
||||
Portainer ne lit pas de fichier `.env` : les variables se déclarent dans l'écran de la pile, section **Environment variables**. Une seule est obligatoire :
|
||||
Portainer ne lit pas de fichier `.env`, mais **aucune variable n'est obligatoire** : la pile démarre telle quelle.
|
||||
|
||||
| Variable | Valeur |
|
||||
|---|---|
|
||||
| `ENCRYPTION_KEY` | `openssl rand -base64 32` |
|
||||
Une seule mérite d'être renseignée dans la section **Environment variables** : `APP_URL`, avec l'adresse publique réelle. Sans elle, les liens des messages — invitations comprises — pointeront vers `localhost` et personne ne pourra les suivre.
|
||||
|
||||
Les autres ont une valeur par défaut utilisable telle quelle : `POSTGRES_PASSWORD`, `POSTGRES_USER`, `POSTGRES_DB`, `APP_PORT` (9317), `APP_URL`.
|
||||
Les autres ont une valeur par défaut utilisable : `POSTGRES_PASSWORD`, `POSTGRES_USER`, `POSTGRES_DB`, `APP_PORT` (9317). `ENCRYPTION_KEY` peut être fournie si vous gérez vos secrets ailleurs ; sinon elle est produite au premier démarrage.
|
||||
|
||||
Renseignez `APP_URL` avec l'adresse publique réelle, sans quoi les liens des messages — invitations comprises — pointeront vers `localhost` et personne ne pourra les suivre.
|
||||
**Après le premier déploiement, relevez la clé dans les journaux du conteneur `app` et conservez-la hors du serveur.**
|
||||
|
||||
### En local
|
||||
|
||||
@@ -97,7 +94,7 @@ pnpm dev
|
||||
openssl rand -base64 32
|
||||
```
|
||||
|
||||
`ENCRYPTION_KEY` n'a **délibérément pas de valeur par défaut**, et n'en aura pas : une clé livrée avec l'image serait connue de quiconque lit ce dépôt, et le chiffrement ne protégerait plus rien. C'est la seule variable qui bloque le démarrage tant qu'elle manque.
|
||||
Elle n'est **pas** livrée avec l'image — une clé publiée dans un dépôt ne protégerait rien. Elle est produite au premier démarrage du conteneur, affichée une fois dans les journaux, et conservée dans le volume `planflow_secrets`. Fournir `ENCRYPTION_KEY` explicitement l'emporte toujours, pour un déploiement qui gère ses secrets par ailleurs — en gardant à l'esprit qu'une variable d'environnement s'affiche dans `docker inspect` et dans l'interface de gestion, ce qui n'en fait pas un meilleur coffre qu'un fichier.
|
||||
|
||||
Elle vit **hors de la base** : une sauvegarde volée ne doit pas suffire à lire ces colonnes. La perdre rend ces données irrécupérables — la sauvegarder séparément et documenter sa rotation. Elle chiffre également les secrets de second facteur et le mot de passe du serveur d'envoi.
|
||||
|
||||
@@ -109,7 +106,7 @@ Deux choses à sauvegarder **ensemble**, plus une à garder à part :
|
||||
|---|---|
|
||||
| Base de données | volume `planflow_db-data` |
|
||||
| Pièces du dossier salarié | volume `planflow_documents` |
|
||||
| `ENCRYPTION_KEY` | **ailleurs**, jamais dans la même sauvegarde |
|
||||
| Clé de chiffrement | volume `planflow_secrets` — **ailleurs**, jamais dans la même sauvegarde |
|
||||
|
||||
Restaurer l'un sans l'autre rend un dossier amputé : les pièces référencées en base pointeraient vers des fichiers absents. Et sans la clé, le volume des documents est illisible — c'est précisément ce qu'on attend de lui si quelqu'un l'emporte.
|
||||
|
||||
|
||||
Reference in new issue
Block a user