Ghostfolio Common — Configuration applicative partagée
Ghostfolio_Common est la couche applicative partagée de Ghostfolio. Elle n'est
pas déployée seule ; elle fournit la configuration propre à Ghostfolio sur laquelle
s'appuient à la fois Ghostfolio_GKE et
Ghostfolio_CloudRun, afin que les deux variantes de
plateforme se comportent de manière identique là où c'est important. Les
utilisateurs finaux ne configurent jamais cette couche directement — elle n'a
aucune entrée propre dans l'interface de déploiement — mais comprendre ce qu'elle
fournit explique les valeurs par défaut que vous voyez dans la documentation des
plateformes.
Pour l'infrastructure qui provisionne et exécute effectivement Ghostfolio, consultez les guides des plateformes (Ghostfolio_GKE, Ghostfolio_CloudRun) et les guides des socles (App_GKE, App_CloudRun, App_Common).
1. Ce que fournit cette couche
| Domaine | Fourni par Ghostfolio_Common | Où cela apparaît |
|---|---|---|
| Secrets cryptographiques | Génère ACCESS_TOKEN_SALT et JWT_SECRET_KEY (deux chaînes aléatoires de 32 caractères) et les stocke dans Secret Manager | Injectés automatiquement ; à récupérer via Secret Manager (voir ci-dessous) |
| Image de conteneur | Encapsule l'image officielle ghostfolio/ghostfolio de Docker Hub avec un point d'entrée cloud personnalisé (reprend la technique de Langfuse_Common) ; construite via Cloud Build | Sortie container_image du déploiement de la plateforme |
| Moteur de base de données | Fixe Cloud SQL for PostgreSQL 15 (ORM Prisma) comme seul moteur pris en charge | §Base de données dans les guides des plateformes |
| Amorçage de la base de données | Définit le job du premier déploiement (db-init), qui crée la base de données, le rôle et les autorisations — PAS de job de migration distinct, car le conteneur de Ghostfolio exécute lui-même les migrations Prisma à chaque démarrage | Sortie initialization_jobs |
| Stockage objet | Aucun — Ghostfolio n'a besoin d'aucun stockage de fichiers/médias en masse | Sortie storage_buckets (toujours []) |
| Paramètres principaux | Définit NODE_ENV=production et le port du conteneur (3333) | Comportement de l'application dans les guides des plateformes |
| Contrôles de santé | Fournit la sonde de démarrage/vivacité par défaut ciblant /api/v1/health (vérifie la base de données et Redis) | §Observabilité dans les guides des plateformes |
2. Secrets cryptographiques dans Secret Manager
Deux secrets sont générés automatiquement et stockés dans Secret Manager — ils ne sont jamais définis en clair et tous deux sont bloquants au démarrage (Ghostfolio n'a de valeur par défaut raisonnable pour aucun des deux) :
ACCESS_TOKEN_SALT— une chaîne aléatoire de 32 caractères. Sert à hacher l'identifiant anonyme « Security Token » que Ghostfolio génère pour le propriétaire du compte lors du premier « Get Started » (il n'existe ni compte administrateur pré-créé ni formulaire e-mail/mot de passe). Le faire tourner après le premier démarrage invalide tous les Security Tokens émis précédemment — les utilisateurs concernés ne peuvent plus s'authentifier avec leur jeton existant.JWT_SECRET_KEY— une chaîne aléatoire de 32 caractères. Sert à signer tous les JWT d'authentification émis après la connexion par Security Token. Le faire tourner invalide immédiatement toutes les sessions actives et oblige chaque utilisateur à se reconnecter.
Récupérez les secrets après le déploiement :
# List secrets for this deployment (names include the resource prefix):
gcloud secrets list --project "$PROJECT" --filter="name~access-token-salt OR name~jwt-secret-key"
# Read a secret version:
gcloud secrets versions access latest --secret=<secret-name> --project "$PROJECT"
Le mot de passe de la base de données est généré et géré séparément par le socle ;
le nom de son secret est indiqué dans les sorties du déploiement de la plateforme
(database_password_secret). Consultez App_Common pour le modèle
partagé de secrets et de Workload Identity.
3. Moteur de base de données et amorçage
Ghostfolio nécessite PostgreSQL 15 (ORM Prisma) ; le moteur est fixé, et MySQL
ou d'autres moteurs ne sont pas pris en charge. Lors du premier déploiement, un job
ponctuel (db-init) s'exécute avec postgres:15-alpine et, de manière
idempotente :
- Attend que PostgreSQL soit joignable,
- Crée (ou met à jour) le rôle de l'application avec le mot de passe généré,
- Crée la base de données de l'application si elle n'existe pas déjà,
- Accorde tous les privilèges sur la base de données et le schéma public,
- Signale au Cloud SQL Auth Proxy de s'arrêter proprement (GKE).
Contrairement à plusieurs autres modules Common, il n'existe pas de job de
migration distinct. Le point d'entrée amont du conteneur de Ghostfolio
(docker/entrypoint.sh) exécute prisma migrate deploy, puis prisma db seed,
puis démarre le serveur — le tout à chaque démarrage du conteneur, dans le même
processus que l'application. Une migration en échec fait planter le conteneur de
manière visible (le script amont utilise set -ex) au lieu de livrer un service
sain face à une base de données vide ; c'est pourquoi aucun job supplémentaire de
garde/vérification n'est nécessaire ici (à comparer avec le modèle
twenty-verify de Twenty).
Le job peut être relancé sans risque. Inspectez directement la base de données avec :
gcloud sql connect <instance-name> --user=<db-user> --database=<db-name> --project "$PROJECT"
4. Image de conteneur et point d'entrée
L'image personnalisée est un mince wrapper FROM ghostfolio/ghostfolio:<version>
— la même technique que celle utilisée par Langfuse_Common pour d'autres
applications reposant sur une image prête à l'emploi. cloud-entrypoint.sh
s'exécute avant la séquence de démarrage propre à Ghostfolio :
- Compose
DATABASE_URLà partir des variablesDB_*injectées par le socle. Le DSN de Ghostfolio est une chaîne de connexion de type URL (postgresql://user:pass@host:port/db?...) ; le point d'entrée n'utilise donc JAMAIS le chemin du socket Unix de Cloud SQL (ses deux-points casseraient l'analyse de l'URL — le même piège que celui documenté pour Vikunja/Logto). Il se connecte toujours en TCP viaDB_IP, en distinguant uniquement si l'hôte résolu est une adresse de bouclage :- Cloud Run :
DB_IPest toujours la véritable IP privée de Cloud SQL →sslmode=require. - GKE :
DB_IPse résout en127.0.0.1lorsque le sidecar cloud-sql-proxy est actif →sslmode=disable.
- Cloud Run :
- Associe
REDIS_AUTHàREDIS_PASSWORD— le socle injecte toujours le secret du mot de passe Redis sous le nom codé en durREDIS_AUTH(non configurable dansApp_CloudRun/App_GKE), mais le client Redis de Ghostfolio litREDIS_PASSWORD(apps/api/src/helper/redis.helper.ts).REDIS_HOSTetREDIS_PORTn'ont pas besoin d'alias. - Délègue au CMD de l'image de base (
/ghostfolio/entrypoint.sh) viaexec "$@"— ce qui exécute la migration Prisma, l'amorçage et le démarrage du serveur, reproduisant exactement le comportement de l'image non encapsulée. Le Dockerfile redéclare explicitement ceCMD— unENTRYPOINTpersonnalisé seul, sansCMDcorrespondant, l'écarterait sinon silencieusement.
5. Paramètres principaux de l'application
Ghostfolio_Common établit l'environnement de base de Ghostfolio :
NODE_ENV = "production".container_port = 3333— leDEFAULT_PORTde Ghostfolio (libs/common/src/lib/config.ts) ; l'application écoute sur0.0.0.0(DEFAULT_HOST) par défaut, aucune surcharge de l'hôte n'est donc nécessaire.- Redis est obligatoire, pas facultatif —
enable_redisdoit être transmis sans condition par les modules applicatifs ; le conditionner àredis_host != ""supprimerait l'injection de repli Redis sur l'IP NFS de la plateforme et laisseraitREDIS_HOSTnon défini. - Pas de câblage
STORAGE_TYPE/GCS — Ghostfolio n'a besoin d'aucun stockage de fichiers/médias en masse.
6. Comportement des sondes de santé
Les sondes par défaut ciblent GET /api/v1/health — le contrôleur de santé propre
à Ghostfolio (apps/api/src/app/health/health.controller.ts) vérifie À LA FOIS la
connexion à la base de données ET celle à Redis, et renvoie 503 tant que les deux
ne sont pas saines ; il fait donc office de véritable barrière de disponibilité
plutôt que de simple ping de vivacité.
- Sonde de démarrage : HTTP, délai initial de 30s, période de 10s, seuil de 12 échecs (~2 minutes au total).
- Sonde de vivacité : HTTP, délai initial de 30s, période de 30s, seuil de 3 échecs.
7. Stockage d'objets
Aucun. Ghostfolio n'a besoin d'aucun stockage de fichiers/médias en masse —
storage_buckets vaut toujours [].
gcloud storage buckets list --project "$PROJECT" # will not show a Ghostfolio-specific bucket
Pour la configuration propre à Ghostfolio visible par l'utilisateur (variables par groupe, sorties et manière d'explorer chaque service depuis la console et la CLI), consultez les guides des plateformes : Ghostfolio_GKE et Ghostfolio_CloudRun.
Guides associés
- Ghostfolio sur Google Cloud Run — cette configuration déployée sur Cloud Run.
- Ghostfolio sur GKE Autopilot — cette configuration déployée sur GKE.
Need RAD to do something it does not do yet? Request it on the roadmap, or vote on what is already there.