← Blogue

Héberger Umami vous-même pour vos statistiques web

Railyard

19 mai 2026 · 10 min de lecture

Suivez ça sur votre propre serveur. Commencer gratuitement, sans carte

Vous voulez savoir combien de personnes ont visité votre site aujourd’hui et d’où elles viennent, sans envoyer chaque affichage de page à une régie publicitaire et sans bannière de témoins. Umami fait exactement ça : un tableau de bord de statistiques à code source ouvert, qui tourne dans un seul conteneur avec une seule base de données Postgres. Ce guide vous mène d’un serveur vide à Umami sur votre propre domaine en HTTPS, avec votre premier site suivi, une sauvegarde que vous savez restaurer et une méthode pour les mises à jour. La dernière partie montre la version en un clic sur Railyard.

Ce guide utilise Umami 3.4.1, la version actuelle, avec Postgres 16. Umami 3 ne prend en charge que Postgres (version 12.14 ou plus récente), donc il n’y a pas d’option MySQL ici.

Ce qu’il vous faut

  • Un serveur. Umami et Postgres sont légers, un petit serveur suffit. Un Hetzner CX23 (2 vCPU, 4 Go de RAM, 40 Go NVMe) coûte 5,99 €/mois hors TVA et laisse de la place pour d’autres applications. Prenez Ubuntu 24.04 ou une autre image récente basée sur Debian.
  • Un domaine ou un sous-domaine que vous pouvez pointer vers le serveur. Ce guide utilise analytics.example.com.
  • Un accès SSH en root ou avec un utilisateur qui a sudo.

Étape 1 : Pointer le DNS vers le serveur et le mettre à jour

Créez le serveur, notez son adresse IPv4 publique et ajoutez chez votre fournisseur DNS un enregistrement A pour analytics.example.com qui pointe vers cette adresse. Faites-le en premier : Caddy ne peut obtenir un certificat qu’une fois que le nom pointe vers votre serveur, et la mise à jour DNS peut prendre quelques minutes.

Connectez-vous ensuite et mettez le système à jour :

ssh root@203.0.113.10
apt update && apt upgrade -y

Vérifiez l’enregistrement depuis votre poste :

dig +short analytics.example.com

Vous devriez voir l’adresse IP de votre serveur. Si rien ne s’affiche encore, continuez et revérifiez avant l’étape 5.

Étape 2 : Installer Docker

Umami, Postgres et Caddy tournent tous dans des conteneurs, donc Docker Engine avec le plugiciel Compose est la seule chose à installer. Le script de Docker configure son dépôt officiel et ses paquets :

curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
docker --version
docker compose version

Vous devriez voir une ligne de version pour Docker et une autre pour Docker Compose.

Étape 3 : Créer les secrets

Créez un dossier pour la pile et générez trois valeurs dans un fichier .env :

mkdir -p /opt/umami/backups
cd /opt/umami
echo "DB_PASSWORD=$(openssl rand -hex 24)" >> .env
echo "APP_SECRET=$(openssl rand -hex 32)" >> .env
echo "TWO_FACTOR_ENCRYPTION_KEY=$(openssl rand -hex 32)" >> .env
chmod 600 .env

À quoi sert chacune, selon la documentation d’Umami :

  • DATABASE_URL est la seule variable strictement obligatoire. Vous la construirez à partir de DB_PASSWORD dans le fichier Compose.
  • APP_SECRET sécurise les jetons d’authentification. Chaque installation devrait avoir la sienne.
  • TWO_FACTOR_ENCRYPTION_KEY est une chaîne hexadécimale de 64 caractères qui chiffre les secrets de double authentification. openssl rand -hex 32 produit exactement ça. Le fichier Compose d’Umami la définit, et elle est nécessaire si vous comptez activer la connexion à deux facteurs.

Vérifiez le fichier :

cat /opt/umami/.env

Vous devriez voir trois lignes, chacune avec une longue valeur aléatoire.

Étape 4 : Écrire le fichier Compose et le Caddyfile

Enregistrez ceci dans /opt/umami/compose.yaml. Il reprend la structure du docker-compose.yml d’Umami, avec des versions fixées au lieu de latest et Caddy devant :

services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config
    depends_on:
      - umami

  umami:
    image: ghcr.io/umami-software/umami:3.4.1
    restart: unless-stopped
    init: true
    environment:
      DATABASE_URL: postgresql://umami:${DB_PASSWORD}@db:5432/umami
      APP_SECRET: ${APP_SECRET}
      TWO_FACTOR_ENCRYPTION_KEY: ${TWO_FACTOR_ENCRYPTION_KEY}
    depends_on:
      db:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:3000/api/heartbeat"]
      interval: 5s
      timeout: 5s
      retries: 5

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

volumes:
  umami-db-data:
  caddy-data:
  caddy-config:

Quelques points à savoir :

  • Seul Caddy publie des ports. Umami écoute sur 3000 et Postgres sur 5432 à l’intérieur du réseau Compose, donc ni l’un ni l’autre n’est joignable depuis Internet.
  • Compose lit ${DB_PASSWORD} et les autres valeurs dans le fichier .env du même dossier.
  • Umami attend que Postgres soit en bonne santé avant de démarrer, et crée ses tables au premier lancement.
  • Le volume caddy-data conserve vos certificats, donc un redémarrage n’en redemande pas de nouveaux.

Enregistrez ensuite ceci dans /opt/umami/Caddyfile, avec votre propre domaine :

analytics.example.com {
	encode zstd gzip
	reverse_proxy umami:3000
}

Caddy lit le domaine dans l’adresse du site, obtient un certificat Let’s Encrypt, redirige le HTTP vers le HTTPS et transmet les requêtes au conteneur umami. Vérifiez les deux fichiers :

cd /opt/umami
docker compose config --quiet && echo "compose ok"
docker compose run --rm --no-deps caddy caddy validate --config /etc/caddy/Caddyfile

Vous devriez voir compose ok, puis Valid configuration à la fin de la sortie de Caddy.

Étape 5 : Démarrer la pile

docker compose up -d
docker compose ps

Après vingt ou trente secondes, vous devriez voir db et umami marqués (healthy), et caddy à Up. Vérifiez l’application depuis son conteneur :

docker compose exec umami curl -s http://localhost:3000/api/heartbeat

Vous devriez voir {"ok":true}. Suivez ensuite l’obtention du certificat :

docker compose logs -f caddy

Vous devriez voir une ligne indiquant que le certificat a été obtenu pour analytics.example.com. Faites Ctrl+C, puis ouvrez https://analytics.example.com dans votre navigateur. Vous devriez voir la page de connexion d’Umami avec un certificat valide.

Étape 6 : Se connecter et changer le mot de passe par défaut

Chaque nouvelle installation d’Umami crée le même compte : nom d’utilisateur admin, mot de passe umami. Connectez-vous avec ce compte et changez le mot de passe tout de suite dans les paramètres de votre profil. Tant que ce n’est pas fait, n’importe qui qui trouve votre page de connexion peut entrer comme administrateur, alors ne laissez pas une installation neuve tourner toute la nuit avec le mot de passe par défaut.

Ajoutez ensuite votre site. Cliquez sur Websites dans la barre latérale, puis sur Add website, entrez un nom et le domaine de votre site, et enregistrez. Cliquez sur Edit sur le nouveau site et copiez le code de la section Tracking code dans le <head> de votre site.

Chargez votre site dans un autre onglet. Vous devriez voir la visite dans le tableau de bord d’Umami en quelques secondes. Sinon, essayez un navigateur sans bloqueur de publicité : la documentation d’Umami précise que les bloqueurs peuvent empêcher le script de suivi de se charger.

Étape 7 : Sauvegarder la base de données

Tout ce qui compte est dans Postgres : votre compte, vos sites et chaque affichage de page. Enregistrez ceci dans /opt/umami/backup.sh :

#!/usr/bin/env bash
set -euo pipefail
cd /opt/umami
docker compose exec -T db pg_dump -U umami umami | gzip > "backups/umami-$(date +%F).sql.gz"
find backups -name 'umami-*.sql.gz' -mtime +14 -delete

Rendez-le exécutable, lancez-le une fois et planifiez-le chaque jour à 3 h avec crontab -e :

chmod +x /opt/umami/backup.sh
/opt/umami/backup.sh
ls -lh /opt/umami/backups
0 3 * * * /opt/umami/backup.sh

Vous devriez voir un fichier .sql.gz de quelques kilo-octets sur une installation neuve, qui grossit à mesure que les données arrivent. Le script garde quatorze jours. Copiez aussi les fichiers hors du serveur (stockage objet, ou une autre machine avec rsync) : une sauvegarde sur le même disque ne survit pas à la perte du serveur.

Une sauvegarde ne compte qu’une fois restaurée. Pour restaurer dans une installation neuve, démarrez seulement la base de données, chargez le fichier, puis démarrez Umami :

docker compose up -d --wait db
gunzip -c backups/umami-2026-05-19.sql.gz | docker compose exec -T db psql -q -U umami umami
docker compose up -d

Charger le fichier dans une base vide avant le démarrage d’Umami évite les conflits avec les tables qu’Umami crée au premier lancement. Vous devriez voir Umami afficher No pending migrations to apply, et retrouver votre compte et vos données.

Étape 8 : Mettre à jour

Umami applique ses migrations de base de données au démarrage, donc une mise à jour se résume à une nouvelle étiquette d’image et un redémarrage. Lisez d’abord les notes de version sur GitHub, faites une sauvegarde, puis changez l’étiquette dans compose.yaml (par exemple de 3.4.1 vers la version suivante) et lancez :

/opt/umami/backup.sh
docker compose pull umami
docker compose up -d umami
docker compose logs -f umami

Vous devriez voir les migrations s’appliquer, puis Next.js annoncer qu’il est prêt. En cas de problème, remettez l’ancienne étiquette et restaurez la sauvegarde de l’étape 7. Gardez Caddy et Postgres à jour de la même façon : docker compose pull et docker compose up -d pour Caddy, alors qu’un changement de version majeure de Postgres (de 16 à 17) demande une exportation et une restauration, pas seulement une nouvelle étiquette.

Le raccourci : le faire avec Railyard

Les étapes 2 à 5, c’est ce que le modèle Umami de Railyard fait pour vous : déployer Umami sur Railyard. Choisissez un serveur, et Railyard construit Umami, crée une base de données Postgres pour lui, relie les deux sans rien à brancher à la main et génère APP_SECRET. L’application reçoit tout de suite une adresse HTTPS, et vous pouvez ajouter votre propre domaine depuis son onglet Domains avec les enregistrements DNS affichés (Domaines et HTTPS).

L’étape 6 s’applique toujours : connectez-vous avec admin / umami et changez le mot de passe immédiatement. Les sauvegardes de l’étape 7 deviennent des sauvegardes Postgres planifiées, avec restauration en un clic, décrites dans Bases de données et sauvegardes.

Le modèle tourne sur un serveur de votre propre compte infonuagique ou sur un serveur que vous avez déjà, donc le coût reste celui du serveur. Le forfait gratuit de Railyard couvre un serveur plus un serveur de bases de données et trois applications, sans carte. Pro coûte 19 $ US/mois et Team 49 $ US/mois, par équipe.

Dépannage

Caddy n’obtient pas de certificat. C’est presque toujours le DNS. Lancez dig +short analytics.example.com et vérifiez que l’adresse IP de votre serveur s’affiche. Assurez-vous aussi que les ports 80 et 443 sont ouverts dans le pare-feu de votre fournisseur, parce que Let’s Encrypt se connecte au serveur pour le valider. Caddy réessaie tout seul, donc une fois le DNS corrigé, suivez docker compose logs -f caddy.

address already in use sur le port 80 ou 443. Un autre programme écoute déjà, souvent un Nginx ou un Apache installé avec l’image. Trouvez-le avec ss -tlnp | grep -E ':(80|443)\s', arrêtez-le et désactivez-le, puis relancez docker compose up -d.

Umami redémarre en boucle. Lancez docker compose logs umami. La cause habituelle est un DATABASE_URL qui ne correspond pas à la base de données. Si vous avez changé DB_PASSWORD après le premier démarrage, Postgres a toujours l’ancien : le mot de passe n’est appliqué qu’à la création du volume. Remettez l’ancienne valeur ou changez-la dans Postgres avec ALTER USER.

Le tableau de bord n’affiche aucune visite. Vérifiez que le code de suivi est dans le <head> de la page chargée, que le domaine du site dans Umami correspond au vôtre, et essayez un navigateur sans bloqueur de publicité. L’onglet réseau de votre navigateur devrait montrer script.js chargé depuis votre domaine Umami.

Le serveur manque de mémoire. Umami et Postgres sont petits, mais sur un serveur partagé avec d’autres applications, le mécanisme du noyau qui tue les processus en manque de mémoire peut arrêter un conteneur. Vérifiez avec dmesg | grep -i "out of memory" et docker stats, puis déplacez quelque chose ailleurs ou agrandissez le serveur.

FAQ

Umami utilise-t-il des témoins? Umami est conçu pour recueillir des statistiques sans témoins, c’est pourquoi beaucoup de sites l’utilisent sans bannière de consentement. Votre besoin dépend quand même des règles qui s’appliquent à vous, alors vérifiez-les.

Une installation Umami peut-elle suivre plusieurs sites? Oui. Ajoutez chacun sous Websites et chacun obtient son propre code de suivi et son propre tableau de bord.

Peut-on le faire tourner sans Docker? Oui. La documentation d’Umami décrit une installation à partir du code source avec Node.js 18.18 ou plus récent, pnpm et une base Postgres, sous un gestionnaire de processus comme PM2. Docker est plus simple à mettre à jour, c’est pourquoi ce guide l’utilise.

Comment passer de Google Analytics à Umami? Umami commence à compter dès que le code de suivi est sur votre site. Gardez les deux scripts sur vos pages un moment si vous voulez comparer les chiffres avant de retirer celui de Google.

Umami est une des applications auto-hébergées les plus simples à bien faire tourner : un conteneur, une base de données et une petite configuration de mandataire. Peu importe la méthode choisie, les bonnes habitudes sont les mêmes : changer le mot de passe par défaut dès le premier jour, et restaurer une sauvegarde au moins une fois pour savoir qu’elle fonctionne.

Pourquoi les gens choisissent Railyard pour ça

  • Votre propre compte infonuagique. Déployez sur DigitalOcean, Hetzner, Vultr, AWS, OVHcloud, ou n'importe quel serveur Linux par SSH, facturé directement par votre fournisseur, sans majoration.
  • Un prix fixe par équipe. L'offre gratuite est gratuite pour toujours : un serveur plus un serveur de base de données, trois applications, sans carte. Pro coûte 19 $ par mois pour jusqu'à cinq serveurs et un nombre illimité d'applications. Team coûte 49 $ par mois avec des serveurs illimités. Aucuns frais par application, par déploiement, par siège ou par gigaoctet.
  • Des gabarits en un clic. Déployez des applications open source, comme des bases de données, des outils d'analyse et des outils de développement, sur votre propre serveur en un clic.
  • Des bases de données gérées. Postgres, MySQL et Redis, avec des sauvegardes planifiées, vérifiées par restauration, et la récupération à un point dans le temps.
  • Déploiement par push. Déployez depuis GitHub, GitLab ou la CLI, avec HTTPS automatique et des mises en production sans interruption.

Déployez Umami en un clic

Le modèle Railyard fait tourner Umami avec Postgres branché et APP_SECRET généré, sur un serveur qui vous appartient.

Offre gratuite, sans carte, et 14 jours de Pro pour chaque nouvelle équipe. Prix fixe par équipe.