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
| Variable | Rôle | Statut |
|---|---|---|
DATABASE_URL | Connexion à la base Postgres | Obligatoire |
BETTER_AUTH_SECRET | Secret aléatoire qui signe les sessions (openssl rand -base64 32) | Obligatoire |
BETTER_AUTH_URL | URL publique de l’instance, par exemple https://compta.votre-societe.fr | Obligatoire |
ADMIN_EMAIL | Le seul email autorisé à créer le compte administrateur | Obligatoire |
RESEND_API_KEY, EMAIL_FROM | Envoi des emails ; sans eux, les emails sont écrits dans les logs | Recommandé |
CRON_SECRET | Protège la synchronisation bancaire quotidienne | Optionnel |
ENCRYPTION_KEY | Chiffre les identifiants bancaires en base ; par défaut, dérivée de BETTER_AUTH_SECRET | Optionnel |
DATABASE_SSL | false pour une base Postgres sans TLS sur un réseau privé (ou ?sslmode=disable dans l’URL) | Optionnel |
SKIP_MIGRATIONS | true pour ne pas appliquer les migrations au démarrage | Optionnel |
KLEDG_BACKUP | off pour ne pas sauvegarder la base avant une migration (activé par défaut) | Optionnel |
KLEDG_BACKUP_DIR, KLEDG_BACKUP_KEEP | Dossier 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ù | Comment | Statut |
|---|---|---|
| Un serveur virtuel (VPS), par exemple chez Hetzner, OVHcloud ou Scaleway, hébergeurs européens | Docker, le fichier compose.prod.yml et Caddy, comme décrit sur cette page | Docker avec Postgres : testé |
| Coolify ou Dokploy, sur votre serveur | Ces outils construisent l’image à partir du Dockerfile du dépôt ; ajoutez une base Postgres et les variables d’environnement | Devraient 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 Neon | Le bouton de déploiement, sans Docker | Testé, 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.