Aller au contenu

Héberger Kledg avec Docker

Installez Kledg sur votre propre serveur avec l’image Docker et Postgres : docker compose, HTTPS avec Caddy, sauvegardes, mises à jour et tâches planifiées.

Le dépôt Kledg contient une image Docker de production. Avec une base Postgres, elle suffit pour faire tourner votre instance sur un serveur que vous contrôlez : un serveur virtuel chez un hébergeur, une machine dans vos locaux, ou une plateforme qui exécute des conteneurs.

Deux configurations sont testées à ce jour : Vercel avec Neon (voir Auto-hébergement) et Docker avec Postgres, décrite ici.

Ce qu’il vous faut

  • un serveur Linux avec Docker et Docker Compose ;
  • un nom de domaine pointant vers ce serveur, par exemple compta.votre-societe.fr ;
  • de préférence, un compte Resend pour l’envoi des emails (mot de passe oublié, accès des membres).

Les variables d’environnement

VariableRôleStatut
DATABASE_URLConnexion à la base PostgresObligatoire
BETTER_AUTH_SECRETSecret aléatoire qui signe les sessions (openssl rand -base64 32)Obligatoire
BETTER_AUTH_URLURL publique de l’instance, par exemple https://compta.votre-societe.frObligatoire
ADMIN_EMAILLe seul email autorisé à créer le compte administrateurObligatoire
RESEND_API_KEY, EMAIL_FROMEnvoi des emails ; sans eux, les emails sont écrits dans les logsRecommandé
CRON_SECRETProtège la synchronisation bancaire quotidienneOptionnel
ENCRYPTION_KEYChiffre les identifiants bancaires en base ; par défaut, dérivée de BETTER_AUTH_SECRETOptionnel
DATABASE_SSLfalse pour une base Postgres sans TLS sur un réseau privé (ou ?sslmode=disable dans l’URL)Optionnel
SKIP_MIGRATIONStrue pour ne pas appliquer les migrations au démarrageOptionnel
KLEDG_BACKUPoff pour ne pas sauvegarder la base avant une migration (activé par défaut)Optionnel
KLEDG_BACKUP_DIR, KLEDG_BACKUP_KEEPDossier des sauvegardes avant migration (/app/backups par défaut) et nombre à conserver (5 par défaut)Optionnel

Installer avec docker compose

Récupérez le code sur le serveur :

git clone https://github.com/kledghq/kledg.git /opt/kledg
cd /opt/kledg

Le fichier docker-compose.yml fourni dans le dépôt sert au développement (une base locale seulement). Pour la production, créez un fichier compose.prod.yml :

services:
  db:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: kledg
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: kledg
    volumes:
      - kledg-db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U kledg -d kledg"]
      interval: 10s
      timeout: 5s
      retries: 5

  kledg:
    build: .
    restart: unless-stopped
    env_file: .env
    environment:
      DATABASE_URL: postgresql://kledg:${POSTGRES_PASSWORD}@db:5432/kledg?sslmode=disable
    ports:
      - "127.0.0.1:3000:3000"
    volumes:
      - ./backups:/app/backups
    depends_on:
      db:
        condition: service_healthy

volumes:
  kledg-db:

Puis un fichier .env à côté, lisible par vous seul (chmod 600 .env) :

POSTGRES_PASSWORD=un-mot-de-passe-long-et-aleatoire
BETTER_AUTH_SECRET=resultat-de-openssl-rand-base64-32
BETTER_AUTH_URL=https://compta.votre-societe.fr
ADMIN_EMAIL=vous@votre-societe.fr
RESEND_API_KEY=
EMAIL_FROM=
CRON_SECRET=resultat-de-openssl-rand-hex-32

Lancez l’instance :

docker compose -f compose.prod.yml up -d --build

Au démarrage, le conteneur applique les migrations de la base, puis lance l’application sur le port 3000. Le port n’est ouvert que sur l’interface locale du serveur : c’est le reverse proxy qui le publie en HTTPS. Pour vérifier que tout répond :

curl http://127.0.0.1:3000/api/health
# {"status":"ok"}

L’image déclare aussi ce point de contrôle comme health check Docker : docker compose ps indique si le conteneur est en bonne santé.

Le HTTPS avec un reverse proxy

Kledg doit être servi en HTTPS. Caddy obtient et renouvelle le certificat tout seul ; installé sur le serveur, il suffit de trois lignes dans son Caddyfile :

compta.votre-societe.fr {
    reverse_proxy 127.0.0.1:3000
}

L’adresse doit correspondre à BETTER_AUTH_URL. Ouvrez-la ensuite dans votre navigateur : la page de configuration crée le compte administrateur avec l’email défini dans ADMIN_EMAIL.

Les sauvegardes

Vos écritures sont dans le volume Postgres. Planifiez un pg_dump quotidien, par exemple dans la crontab du serveur (crontab -e) :

0 2 * * * cd /opt/kledg && docker compose -f compose.prod.yml exec -T db pg_dump -U kledg -Fc kledg > /var/backups/kledg/kledg-$(date +\%F).dump

Copiez ces fichiers hors du serveur (stockage objet, autre machine), supprimez les plus anciens, et testez une restauration de temps en temps avec pg_restore. Les livres comptables se conservent dix ans : gardez aussi l’export FEC de chaque exercice clôturé.

La synchronisation bancaire quotidienne

Sur Vercel, une tâche planifiée synchronise Qonto chaque jour. Ailleurs, planifiez vous-même l’appel, avec le secret défini dans CRON_SECRET. Dans la crontab du serveur :

0 5 * * * curl -fsS -H "Authorization: Bearer VOTRE_CRON_SECRET" https://compta.votre-societe.fr/api/cron/sync-qonto

Ou depuis une GitHub Action planifiée, avec le secret enregistré dans votre dépôt :

on:
  schedule:
    - cron: "0 5 * * *"
jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - run: curl -fsS -H "Authorization: Bearer ${{ secrets.CRON_SECRET }}" https://compta.votre-societe.fr/api/cron/sync-qonto

Mettre à jour

Sur le serveur, récupérez la nouvelle version puis reconstruisez l’image :

cd /opt/kledg
git pull
docker compose -f compose.prod.yml up -d --build

Au redémarrage, si la nouvelle version apporte des migrations, le conteneur sauvegarde d’abord la base avec pg_dump dans le dossier backups (les cinq dernières sont conservées), puis applique les migrations. Si la sauvegarde échoue, le conteneur s’arrête sans toucher à la base. Lisez les notes de version avant une mise à jour.

Pour revenir en arrière, redémarrez l’ancienne version et restaurez la sauvegarde :

docker compose -f compose.prod.yml exec -T db pg_restore -U kledg -d kledg --clean --if-exists < backups/kledg-AAAAMMJJTHHMMSSZ.dump

Les migrations de Kledg sont uniquement additives : une version ne supprime jamais une colonne encore utilisée par la version précédente.

Si le serveur clone votre propre copie du dépôt sur GitHub plutôt que kledghq/kledg, le workflow Update from Kledg y ouvre chaque semaine une pull request « Mise à jour Kledg x.y.z » : fusionnez-la, puis lancez les commandes ci-dessus.

Où faire tourner l’image

OùCommentStatut
Un serveur virtuel (VPS), par exemple chez Hetzner, OVHcloud ou Scaleway, hébergeurs européensDocker, le fichier compose.prod.yml et Caddy, comme décrit sur cette pageDocker avec Postgres : testé
Coolify ou Dokploy, sur votre serveurCes outils construisent l’image à partir du Dockerfile du dépôt ; ajoutez une base Postgres et les variables d’environnementDevraient fonctionner car elles exécutent des images Docker, mais ne sont pas encore testées
Une base Postgres managée (Neon, ou l’offre Postgres de votre hébergeur)Retirez le service db et pointez DATABASE_URL vers la base managée, en TLS (comportement par défaut)Neon : testé avec Vercel ; les autres offres (Postgres 15 ou plus) devraient fonctionner, mais ne sont pas encore testées
Vercel avec NeonLe bouton de déploiement, sans DockerTesté, voir Auto-hébergement

Les tarifs dépendent de chaque hébergeur et évoluent : vérifiez-les avant de choisir. Si vous ne souhaitez pas vous en occuper, l’installation accompagnée est sur devis.

Cette documentation aide à comprendre et à utiliser Kledg. Elle ne remplace pas les conseils d’un expert-comptable : en cas de doute sur votre situation, faites-vous accompagner.