Funk-lab/admin/k8s/ghostfolio.md
Alkatrazz b615e9e0fd docs(ghostfolio): sslmode=disable + caveat grant schema public
Corrige la procédure : sslmode=disable (PG s01 sans SSL, seed Prisma 7.x échoue
en TLS sinon) et documente le GRANT ALL ON SCHEMA public requis pour les bases
possédées par postgres.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 14:20:05 +02:00

5.4 KiB

Ghostfolio — Suivi & analyse de portefeuille

Ghostfolio est l'outil de suivi de patrimoine du lab : actions, ETF, crypto. Il fournit le suivi de performance (TWR / ROI), les dividendes, l'allocation, l'analyse de risque (« X-Ray »). Open-source (AGPL-3.0), self-hosté, données dans PostgreSQL sur storage-01.


Accès

URL http://ghostfolio.lab.local
Namespace k8s ai
Port interne 3333
Données de marché Yahoo Finance (gratuit, sans clé API) par défaut

Architecture

ghostfolio (pod)  →  PostgreSQL  192.168.10.1:5432  (base « ghostfolio », hors cluster)
                  →  ghostfolio-redis:6379           (cache, in-cluster)
  • PostgreSQL : base + utilisateur ghostfolio créés par le rôle Ansible postgresql (mot de passe vault vault_pg_ghostfolio_password). Schéma géré par Ghostfolio (migrations Prisma au démarrage) — pas de table à créer à la main.
  • Redis : déployé dans le cluster (redis:7-alpine, k8s/apps/ghostfolio/redis.yaml), mot de passe via le même secret. Pas de persistance (cache uniquement).
  • Pas de PVC : Ghostfolio est sans état, tout vit dans PostgreSQL + Redis.

Déploiement (ArgoCD)

Manifests dans k8s/apps/ghostfolio/ :

  • deployment.yaml — pod Ghostfolio (:3333)
  • redis.yaml — Deployment + Service Redis (cache)
  • service.yaml — ClusterIP :3333
  • ingress.yaml — IngressRoute Traefik

Application ArgoCD : k8s/apps-of-apps/apps/ghostfolio.yaml

Image épinglée sur :latest (cohérent avec n8n). Pour figer une version, remplacer par ghostfolio/ghostfolio:<tag> dans deployment.yaml.


Mise en service (ordre des opérations)

1. Créer la base PostgreSQL sur storage-01

Ajouter le secret au vault Ansible (depuis la racine du repo — la cible fait le cd seule) :

make vault-edit   # ajouter : vault_pg_ghostfolio_password: "<mot de passe fort>"

La base et l'utilisateur ghostfolio sont déjà déclarés dans ansible/roles/postgresql/defaults/main.yml. Appliquer :

ansible-playbook -i inventory.yml playbooks/storage-01.yml --tags postgresql

2. Créer le secret k8s (non commité)

kubectl create secret generic ghostfolio-secret -n ai \
  --from-literal=database-url="postgresql://ghostfolio:PG_PASSWORD@192.168.10.1:5432/ghostfolio?connect_timeout=300&sslmode=disable" \
  --from-literal=redis-password="$(openssl rand -hex 16)" \
  --from-literal=access-token-salt="$(openssl rand -hex 32)" \
  --from-literal=jwt-secret-key="$(openssl rand -hex 32)"
  • PG_PASSWORD = la valeur mise dans vault_pg_ghostfolio_password à l'étape 1.
  • sslmode=disable est obligatoire : PostgreSQL sur s01 n'a pas SSL activé, et l'adapter pg de Prisma 7.x (étape de seed Ghostfolio) échoue en TlsConnectionError avec prefer. Le LAN cluster est interne/de confiance, donc pas de TLS requis ici.
  • redis-password peut être n'importe quelle valeur aléatoire (Redis est interne au cluster).
  • access-token-salt / jwt-secret-key doivent rester stables : les régénérer invaliderait les sessions et les comptes existants.

3. Pousser sur Git → ArgoCD synchronise

git add k8s/apps/ghostfolio/ k8s/apps-of-apps/apps/ghostfolio.yaml \
        ansible/roles/postgresql/defaults/main.yml admin/k8s/ghostfolio.md
git commit -m "feat(ghostfolio): suivi de portefeuille sur k8s (PG s01 + Redis)"
git push

ArgoCD crée l'app (~3 min). Au premier démarrage Ghostfolio applique ses migrations Prisma.

4. Créer le compte admin

À la première connexion sur http://ghostfolio.lab.local, le premier utilisateur créé devient administrateur. Saisie des positions ensuite via l'UI ou import CSV.


Dépannage

# Logs du pod
kubectl logs -n ai deploy/ghostfolio --tail=50

# Vérifier l'accès PostgreSQL depuis le pod
kubectl exec -n ai deploy/ghostfolio -- env | grep -i database  # (masqué : secret)

# Santé applicative
kubectl exec -n ai deploy/ghostfolio -- wget -qO- http://localhost:3333/api/v1/health

# Redis joignable ?
kubectl get pods -n ai -l app=ghostfolio-redis
  • CrashLoop au 1er démarrage : souvent la base inaccessible (mot de passe database-urlvault_pg_ghostfolio_password, ou rôle postgresql pas réappliqué). Vérifier nftables (port 5432 ouvert pour 192.168.10.0/24, déjà le cas) et pg_hba.conf (host scram-sha-256 pour le LAN cluster, déjà le cas).
  • Error: permission denied for schema public (migrations Prisma) : la base ghostfolio est possédée par postgres (le rôle postgresql_db ne fixe pas owner:), donc l'utilisateur ghostfolio n'a pas de droit implicite sur le schéma public. Les bases historiques (n8n/openwebui/litellm) sont possédées par leur user et n'ont jamais eu ce souci. Correctif (idempotent, identique à la task Ansible « Grant schema public ») :
    ssh storage-01 "sudo -u postgres psql -d ghostfolio -c 'GRANT ALL ON SCHEMA public TO ghostfolio;'"
    
    Vérifier : \dn+ public doit montrer ghostfolio=UC.
  • Error opening a TLS connection: The server does not support SSL (seed Prisma 7.x) : PostgreSQL sur s01 n'a pas SSL → database-url doit finir par sslmode=disable, pas prefer.
  • Quotes/prix vides : Yahoo Finance peut throttler ; les prix se mettent à jour via le scheduler interne. Optionnellement ajouter une clé d'un autre data provider plus tard.