SSD Nodes Learn 🎉 VPS dès $4.99/mois
Guides Matt ConnorPar Matt Connor

Alternatives auto-hébergées à Calendly : comparatif

Comparez Cal.com, Easy!Appointments, Rallly et DayOtter sur un VPS selon deux critères décisifs : synchronisation bidirectionnelle des calendriers et e-mails sortants.

La réponse courte

Une alternative auto-hébergée à Calendly doit faire une chose que les outils internes de votre VPS ne font jamais : répondre au public. La page de réservation est le produit. Elle a besoin d’un vrai nom de domaine et de TLS (Transport Layer Security) dès le premier jour. Elle doit aussi envoyer des e-mails à des personnes qui n’ont jamais entendu parler de votre serveur.

Quatre projets couvrent les options réalistes. Cal.com est l’alternative la plus proche de Calendly et le choix par défaut pour un consultant indépendant. Easy!Appointments est léger, fonctionne avec PHP et MySQL et se contente d’un VPS de 1 GB. Rallly est un outil de sondage de groupe et ne possède aucune page de réservation. DayOtter est le projet le plus récent : il s’agit d’une plateforme de planification sous AGPLv3, avec un assistant de confirmation en amont.

Deux questions déterminent celui que vous pouvez réellement exploiter. Se synchronise-t-il dans les deux sens avec le calendrier que vous utilisez déjà ? Et peut-il envoyer des e-mails ? C’est sur le second point que la plupart des configurations de réservation auto-hébergées échouent discrètement. Nous allons donc commencer par là.

Les e-mails sortants sont la partie qui échoue

Une confirmation de réservation arrive dans la boîte de réception d’un inconnu. Il s’agit d’un e-mail transactionnel envoyé vers Gmail ou Microsoft 365. Ces services évaluent votre envoi selon l’adresse IP d’envoi et vos enregistrements DNS.

Envoyer directement depuis le VPS ne fonctionne presque jamais. La plupart des fournisseurs bloquent le port TCP sortant 25 sur les nouveaux comptes. La connexion reste donc bloquée, puis expire. Même lorsque le port 25 est ouvert, une nouvelle adresse IP de VPS n’a aucun historique d’envoi. Les grands fournisseurs considèrent les adresses inconnues appartenant à des plages d’hébergement comme suspectes. La réservation est enregistrée dans la base de données, la page indique qu’elle est confirmée, mais personne ne reçoit d’e-mail. Rien ne semble défaillant du côté du serveur. C’est pourquoi le problème est souvent découvert plusieurs semaines plus tard par un client qui ne s’est jamais présenté.

Utilisez un relay. N’importe quel fournisseur d’e-mails transactionnels convient. L’application a seulement besoin d’un hostname, d’un port, d’un nom d’utilisateur et d’un mot de passe. Vérifiez que le port est accessible avant de modifier la configuration de l’application :

nc -vz -w 5 "$SMTP_HOST" 587

Une ligne succeeded indique que le chemin est ouvert. Un blocage ou Connection refused signifie que le port est bloqué au niveau du réseau. Modifier .env ne résoudra rien. Les relays utilisent le port 587 ou 465 précisément parce que le port 25 est si souvent bloqué.

Chaque projet utilise le relay à sa manière. Cal.com lit EMAIL_FROM, EMAIL_SERVER_HOST, EMAIL_SERVER_PORT, EMAIL_SERVER_USER et EMAIL_SERVER_PASSWORD. Il accepte aussi RESEND_API_KEY à la place. Vérifiez bien ce point : le .env.example fourni par défaut pointe EMAIL_SERVER_HOST vers localhost sur le port 1025. Il s’agit d’une boîte aux lettres locale destinée au développement. Si vous conservez la valeur par défaut, l’application envoie les e-mails dans le vide sans afficher d’erreur. Rallly utilise SMTP_HOST, SMTP_PORT, SMTP_USER et SMTP_PWD. DayOtter utilise des paramètres SMTP ou une clé Resend. Easy!Appointments envoie ses notifications depuis l’application. Configurez-le donc avec le même relay dans sa page de paramètres avant d’accepter une vraie réservation.

Publiez ensuite les enregistrements DNS fournis par votre relay. Un enregistrement SPF (sender policy framework) indique quels serveurs peuvent envoyer des e-mails pour votre domaine. Une clé DKIM (domainkeys identified mail) signe chaque message afin que le destinataire puisse vérifier qu’il n’a pas été modifié. Ajoutez une policy DMARC (domain-based message authentication, reporting and conformance) une fois ces deux mécanismes validés. Envoyez une réservation de test vers une adresse réelle chez un grand fournisseur, ouvrez les en-têtes du message et vérifiez que les lignes d’authentification indiquent pass. Une page de réservation qui ne peut pas envoyer d’e-mails est pire que l’absence de page de réservation, car l’échec est silencieux.

Quels backends de calendrier se synchronisent réellement dans les deux sens

La synchronisation fonctionne dans deux directions, qui peuvent échouer séparément. La lecture fournit les disponibilités : l’application doit voir vos plages déjà occupées, sinon elle proposera un créneau pendant lequel vous avez déjà un engagement. L’écriture correspond à la réservation : l’événement confirmé doit apparaître dans le calendrier que vous consultez réellement, et pas uniquement dans l’outil de réservation.

Google Calendar et Microsoft 365 prennent en charge les deux directions, à une condition pour une installation auto-hébergée. Vous devez créer vous-même le client OAuth (autorisation ouverte), car l’ID client du produit hébergé ne figure pas dans le code source. Pour Cal.com, il s’agit de GOOGLE_API_CREDENTIALS dans .env, qui contient le fichier JSON téléchargé depuis la console Google Cloud. DayOtter utilise de la même manière les identifiants OAuth de Google et de Microsoft.

Deux problèmes peuvent survenir ici, et il vaut mieux les connaître avant de commencer. Premièrement, l’URI de redirection enregistrée doit correspondre exactement à votre URL publique, y compris le schéma et l’éventuel chemin final. Sinon, Google interrompt la connexion avec redirect_uri_mismatch sur l’écran de consentement. Deuxièmement, un projet Google dont le statut de publication est Testing génère des refresh tokens qui expirent au bout de sept jours. La synchronisation fonctionne pendant une semaine, puis s’arrête, et les journaux de l’application affichent invalid_grant lors du renouvellement suivant. Passez l’écran de consentement à In production, ou acceptez de vous reconnecter manuellement chaque lundi.

CalDAV (extensions de calendrier pour WebDAV) est l’option ouverte, mais sa prise en charge est plus limitée. Cal.com fournit une application CalDAV encore marquée comme bêta, vérifiée avec des serveurs tels que Baikal, Radicale, Nextcloud et Kerio Connect. Apple iCloud fonctionne avec la même application, mais nécessite un mot de passe spécifique à l’application au lieu du mot de passe de votre identifiant Apple. DayOtter répertorie Apple via CalDAV aux côtés de Google et de Microsoft 365.

Un flux ICS n’est pas une synchronisation. Une URL .ics à laquelle on s’abonne est conçue pour être en lecture seule. Elle peut donc bloquer des créneaux sur votre page de réservation, mais elle ne peut jamais recevoir la réservation. Si un outil ne propose que ICS pour votre calendrier, vous ne disposez que de la moitié du mécanisme et devrez toujours copier les événements manuellement.

Easy!Appointments synchronise uniquement Google Calendar. Rallly ne lit pas du tout les disponibilités : il recueille les votes sur un ensemble de dates proposées. C’est l’outil adapté à la question « quand les six participants peuvent-ils se réunir ? », mais pas à la réservation d’un créneau de 30 minutes avec vous.

Une page de réservation est publique : TLS est prioritaire

La plupart des services auto-hébergés sont privés. Un wiki, un tableau de suivi ou un dashboard peuvent rester derrière un VPN ou une authentification SSO, sans jamais être exposés sur Internet. Ce n’est pas le cas d’un lien de réservation. Toute personne à qui vous l’envoyez doit pouvoir le charger. Cela modifie la configuration de trois façons concrètes.

Vous avez besoin d’un nom de domaine avec un enregistrement A pointant vers le VPS, avant d’installer quoi que ce soit. Vous avez besoin d’un certificat dès le premier jour, car les navigateurs signalent qu’un formulaire HTTP simple n’est pas sécurisé et votre client y saisit son nom et son adresse e-mail. Vous devez également définir correctement l’URL publique de l’application dans sa configuration. Cette valeur est intégrée aux liens des e-mails sortants et aux URI de redirection OAuth. Définissez NEXT_PUBLIC_WEBAPP_URL dans Cal.com, DOMAIN dans Rallly, BASE_URL dans Easy!Appointments ou DAYOTTER_DOMAIN lors de l’installation, puis indiquez l’adresse https:// que vous utiliserez réellement.

Rallly et DayOtter gèrent TLS pour vous. La stack incluse avec Rallly contient Traefik et émet des certificats Let’s Encrypt en utilisant l’adresse indiquée dans ACME_EMAIL. L’installateur de DayOtter démarre Caddy avec HTTPS automatique. Cal.com et Easy!Appointments ne le font pas. Vous devez donc placer nginx devant l’application et émettre vous-même le certificat, comme pour un certificat Let’s Encrypt sur nginx avec Certbot. Liez le conteneur de l’application à 127.0.0.1 afin que le proxy que vous contrôlez soit le seul point d’accès. Si le même serveur exécute déjà une alternative auto-hébergée à Trello pour vos tableaux internes, laissez-la derrière votre authentification existante et rendez public uniquement le server block de l’hôte de réservation.

Cal.com sur votre VPS

La configuration Docker se trouve dans son propre dépôt et les images sont déjà construites sur Docker Hub. Vous devez donc les récupérer au lieu de les construire.

git clone --recursive https://github.com/calcom/cal.diy.git
cd cal.diy
cp .env.example .env
openssl rand -base64 32
openssl rand -base64 24
docker compose pull
docker compose up -d

La première valeur aléatoire va dans NEXTAUTH_SECRET et la seconde dans CALENDSO_ENCRYPTION_KEY. Les deux sont obligatoires. Définissez DATABASE_URL et faites pointer NEXT_PUBLIC_WEBAPP_URL vers votre adresse publique. La stack fournie comprend l’application web, PostgreSQL et Prisma Studio. La documentation indique docker compose up -d calcom pour exécuter uniquement l’application avec une base de données hébergée ailleurs. C’est ce qu’il faut utiliser une fois l’installation stabilisée.

Récupérez l’image. Ne la construisez pas sur le VPS. Les instructions du projet demandent d’exporter NODE_OPTIONS="--max-old-space-size=16384" lors d’une construction depuis les sources. Cette valeur correspond à un heap de 16 GB pour Node seul. Sur une machine ARM, ajoutez le suffixe -arm au tag de l’image. Le projet ne publie aucune valeur minimale pour exécuter l’image préconstruite. Retenez donc 2 GB pour l’application et PostgreSQL comme estimation pratique, et non comme valeur documentée. Surveillez la mémoire pendant la première semaine.

Vérifiez que le service a démarré :

docker compose ps
docker compose logs -f calcom
curl -sI https://cal.example.com | head -n 1

La commande curl doit afficher HTTP/2 200. Une réponse 502 Bad Gateway de nginx alors que le conteneur apparaît comme actif signifie généralement que le premier démarrage applique encore les migrations de la base de données. Attendez quelques minutes et consultez les journaux avant de conclure à une panne. Les webhooks de Cal.com sont déclenchés pour chaque réservation confirmée. Une réservation peut donc lancer l’automatisation que vous utilisez déjà, par exemple une instance n8n accessible en HTTPS sur votre VPS.

Le cœur du projet est sous licence AGPLv3. Certaines fonctionnalités se trouvent dans un répertoire enterprise sous une licence commerciale distincte. Lisez cette licence avant de créer un processus métier payant reposant sur les fonctionnalités d’équipe.

Easy!Appointments sur une machine de 1 GB

Les prérequis sont Apache ou Nginx, PHP 8.2 ou version ultérieure, ainsi que MySQL. Une image officielle est disponible à l’adresse alextselegidis/easyappointments.

Un avertissement avant de commencer. Le docker-compose.yml du dépôt est un environnement de développement. Il vous demande d’ouvrir un shell dans le conteneur et d’exécuter npm install && composer install && npm start. Ce n’est pas une configuration de production. Utilisez plutôt l’image publiée :

services:
  easyappointments:
    image: alextselegidis/easyappointments  # pin the current tag from Docker Hub
    environment:
      - BASE_URL=https://book.example.com
      - DB_HOST=mysql
      - DB_NAME=easyappointments
      - DB_USERNAME=easyapp
      - DB_PASSWORD=change-me
    ports:
      - '127.0.0.1:8080:80'
    depends_on:
      - mysql
  mysql:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=change-me-too
      - MYSQL_DATABASE=easyappointments
      - MYSQL_USER=easyapp
      - MYSQL_PASSWORD=change-me
    volumes:
      - ./mysql:/var/lib/mysql

BASE_URL doit être l’adresse HTTPS publique. Si sa valeur est incorrecte, les liens de réservation inclus dans les e-mails de confirmation pointeront vers un hôte inaccessible à votre client. L’image fournit du HTTP simple sur le port 80 et ne possède pas son propre certificat. C’est pourquoi le port est lié à 127.0.0.1 et qu’nginx assure la terminaison TLS en amont. Si la syntaxe de Compose ne vous est pas familière, commencez par les bases de Docker Compose sur un VPS, puis revenez ici.

C’est de loin l’option la plus légère de cette sélection. Deux conteneurs, une application PHP et MySQL, fonctionnent sans difficulté sur un VPS de 1 GB. En contrepartie, les possibilités sont limitées : Google Calendar est le seul backend de calendrier, et l’interface est un panneau d’administration traditionnel plutôt qu’un parcours de réservation moderne. Si votre calendrier utilise Microsoft 365, Fastmail ou Nextcloud, cette solution est à écarter d’emblée.

Rallly pour les sondages de groupe

Rallly répond à une autre question. Il ne publie pas vos disponibilités. Il propose à un groupe plusieurs créneaux candidats et recueille les votes. C’est ce qu’il faut pour organiser une réunion du conseil d’administration, mais cela ne convient pas à un lien de réservation client.

curl -fsSL https://get.rallly.co | bash

Lisez toujours un script avant de l’envoyer vers un shell. Remplacez bash par less, vérifiez ce qu’il fait, puis exécutez-le. La procédure manuelle effectue le même travail, en plusieurs étapes que vous pouvez contrôler :

git clone https://github.com/lukevella/rallly-selfhosted.git
cd rallly-selfhosted
./rallly.sh setup
./rallly.sh start

La documentation indique au minimum 2 GB de RAM, Docker 19.03 ou une version ultérieure avec Compose v2, les ports 80 et 443 libres, ainsi qu’un domaine pointant vers le serveur. La stack fournie comprend Traefik pour HTTPS, l’application web, PostgreSQL et Garage pour le stockage d’objets compatible S3. Définissez DOMAIN, un SECRET_PASSWORD d’au moins 32 caractères, SUPPORT_EMAIL et INITIAL_ADMIN_EMAIL. Si vous utilisez déjà un reverse proxy, définissez PROXY_MODE=external et WEB_PORT ; Traefik ne gênera alors pas son fonctionnement. Si vous utilisez déjà un stockage d’objets auto-hébergé compatible S3 avec MinIO, définissez les variables S3_* pour l’utiliser et supprimez le conteneur Garage.

SMTP est indispensable ici, car la connexion se fait par magic link. Sans relay fonctionnel, personne ne peut se connecter, y compris le compte administrateur que vous venez de créer. C’est le scénario favorable en cas de problème d’e-mail : il vous bloque dès la connexion au lieu de faire perdre la réservation d’un client trois semaines plus tard.

DayOtter, le nouvel arrivant

DayOtter est une plateforme de planification sous licence AGPLv3, avec un assistant intégré. L’installation en production tient en une commande :

curl -fsSL https://raw.githubusercontent.com/Dayotter/dayotter/main/deploy/install.sh \
  | sudo DAYOTTER_DOMAIN=cal.example.com bash

Lisez-la avant de l’exécuter, comme indiqué plus haut. L’installateur configure Docker, génère les secrets et démarre toute la stack : l’application web Next.js, un worker en arrière-plan qui gère les rappels, la synchronisation des calendriers et les webhooks, PostgreSQL, Redis et Caddy avec HTTPS automatique.

La prise en charge des calendriers est la plus large des quatre solutions. Elle couvre Google, Microsoft 365, Apple via CalDAV et les flux ICS, avec la réserve concernant ICS indiquée plus haut. Toutes les autres intégrations sont facultatives et se configurent via des variables d’environnement, notamment SMTP ou Resend pour l’envoi d’e-mails, ANTHROPIC_API_KEY pour l’assistant, Twilio pour les SMS et Stripe pour les paiements. L’assistant fonctionne avec une confirmation préalable : il propose une action, vous l’approuvez, et rien n’est ajouté à votre calendrier sans réponse explicite. Si vous laissez la clé API vide, cette partie du produit ne s’exécute tout simplement pas.

La licence est claire pour l’auto-hébergement. Le cœur du projet est sous licence AGPLv3, et un répertoire ee/ contient une licence commerciale réservée au cloud, qui reste inactive tant que DAYOTTER_CLOUD=1 n’est pas défini. Vous pouvez donc utiliser sur votre propre serveur les fonctionnalités d’équipe que l’offre hébergée facture $9 par utilisateur et par mois, en août 2026.

C’est aussi la stack la plus lourde de cette sélection et le projet le plus récent. Faites-la fonctionner à côté de votre lien de réservation existant pendant deux semaines, prenez de vraies réservations via les deux solutions et consultez les journaux du worker avant de migrer vos clients.

Ce que chaque stack vous coûte réellement

Le nombre de conteneurs est un indicateur fiable de la charge qu’une stack imposera à un petit VPS, car chaque service possède son propre seuil minimal de mémoire. Ces chiffres proviennent de la stack Docker publiée par chaque projet et ont été relevés en août 2026.

ChartServices in each project's documented Docker stack
The data behind this chart
[
  {
    "tool": "Easy!Appointments",
    "containers": 2,
    "database": "MySQL"
  },
  {
    "tool": "Cal.com",
    "containers": 3,
    "database": "PostgreSQL"
  },
  {
    "tool": "Rallly",
    "containers": 4,
    "database": "PostgreSQL"
  },
  {
    "tool": "DayOtter",
    "containers": 5,
    "database": "PostgreSQL and Redis"
  }
]

Easy!Appointments nécessite 2 conteneurs et fonctionne avec 1 GB de RAM. La stack fournie avec Rallly en utilise 4, et sa documentation demande 2 GB de RAM. L’installeur de DayOtter démarre 5, ce qui explique pourquoi ce service nécessite le plus grand VPS de ce comparatif, qui en compte 4. Cal.com et DayOtter ne publient aucun chiffre de mémoire minimal ; je pars donc sur 2 GB pour les deux, sans que cela constitue une valeur officiellement prise en charge.

Deux de ces chiffres diminuent si votre infrastructure existe déjà. Les conteneurs Traefik et Garage de Rallly ne sont plus nécessaires si vous utilisez votre propre proxy et votre propre stockage objet. Prisma Studio de Cal.com est un outil de développement que vous ne devez pas laisser actif sur un serveur public.

Quelle alternative auto-hébergée à Calendly devriez-vous choisir

Un consultant indépendant devrait utiliser Cal.com. C’est le seul projet présenté ici qui associe une page de réservation reconnaissable, des images prêtes à l’emploi qui vous évitent une compilation Node sur votre VPS, et une prise en charge de CalDAV pour ceux qui n’utilisent pas de calendrier Google ou Microsoft. Une base PostgreSQL et un conteneur d’application représentent une charge de maintenance que vous pouvez assumer pendant des années. Prévoyez un après-midi pour le client OAuth et le relais de messagerie. Notez aussi que l’application CalDAV est encore en bêta : testez une réservation réelle de bout en bout avant de publier le lien.

Une petite équipe devrait étudier DayOtter. Le round robin pondéré et les réservations collectives sont intégrés au cœur sous licence AGPLv3. L’auto-hébergement vous donne donc les fonctionnalités facturées par une offre hébergée, et le processus worker est conçu pour les rappels et les webhooks dont une équipe se sert réellement. Le compromis concerne la maturité : c’est le projet le plus récent de cette liste. Exécutez-le d’abord en parallèle et conservez l’ancien lien jusqu’à ce que vous ayez observé un mois complet de réservations.

Deux cas plus ciblés. Si vous avez seulement besoin d’un sondage pour trouver un horaire qui convient au groupe, installez Rallly et arrêtez-vous là. Si vous disposez d’un VPS de 1 GB, utilisez Google Calendar et voulez la solution la plus légère capable de gérer une réservation, Easy!Appointments restera utilisable plus longtemps que toutes les options plus complexes que vous pourriez installer sur cette machine. Pour savoir quelles autres applications méritent une place sur le même serveur, consultez ce qui mérite d’être auto-hébergé en 2026.

FAQ

Puis-je utiliser une page de réservation auto-hébergée sans nom de domaine ?

Non. Toutes ces applications inscrivent leur URL publique dans les liens des e-mails de confirmation. Google et Microsoft comparent également l’URI de redirection OAuth à cette même valeur. Une simple adresse IP produit donc redirect_uri_mismatch sur l’écran de consentement. Let’s Encrypt ne délivre pas non plus de certificat pour une adresse IP. La page est alors accessible en HTTP simple et le navigateur indique que le formulaire n’est pas sécurisé. Achetez d’abord le domaine, créez un enregistrement A pointant vers le VPS, puis procédez à l’installation.

Pourquoi mes e-mails de confirmation de réservation n’arrivent-ils jamais ?

C’est presque toujours parce que le serveur essaie de remettre lui-même les e-mails. La plupart des fournisseurs de VPS bloquent le port sortant 25 sur les nouveaux comptes. La connexion reste donc bloquée. Même lorsque le port est ouvert, une nouvelle adresse IP n’a aucune réputation d’envoi et les grands fournisseurs refusent les messages. Configurez l’application avec un relais de messagerie transactionnelle sur le port 587. Vérifiez que le port est accessible avec nc -vz -w 5 "$SMTP_HOST" 587, puis publiez les enregistrements SPF et DKIM fournis par le relais. Si vous utilisez Cal.com, vérifiez que vous avez remplacé les valeurs par défaut EMAIL_SERVER_HOST=localhost et EMAIL_SERVER_PORT=1025 fournies avec l’application. Elles pointent vers une boîte aux lettres de développement locale.

Cal.com auto-hébergé se synchronise-t-il avec CalDAV, ou uniquement avec Google ?

Les deux, avec un niveau de maturité différent. L’application CalDAV est indiquée comme étant en version bêta. Elle est vérifiée avec plusieurs serveurs, notamment Baikal, Radicale, Nextcloud et Kerio Connect. Apple iCloud fonctionne également avec une app-specific password. Google Calendar et Microsoft 365 se synchronisent dans les deux sens. Toutefois, sur une installation auto-hébergée, vous devez créer votre propre client OAuth et le fournir via GOOGLE_API_CREDENTIALS, car les identifiants du service hébergé ne figurent pas dans le code source.

Pourquoi la synchronisation avec Google Calendar cesse-t-elle de fonctionner après une semaine ?

Parce que le projet Google Cloud utilise encore le statut de publication Testing. Google délivre aux applications dans cet état des refresh tokens qui expirent après sept jours. La connexion fonctionne donc, puis échoue lors du renouvellement suivant du token. Le journal de l’application affiche alors invalid_grant. Passez l’écran de consentement OAuth à In production, puis reconnectez le calendrier une fois. Le reconnecter sans modifier ce statut vous accorde sept jours supplémentaires, pas davantage.

Lesquelles de ces applications fonctionneront sur un VPS de 1 GB ?

Easy!Appointments fonctionnera, car il s’agit d’une application PHP avec MySQL. Rallly documente un minimum de 2 GB et sa stack intégrée exécute quatre services. Cal.com et DayOtter ne publient aucun minimum. Toutefois, une application Next.js avec PostgreSQL, ainsi que Redis et un worker dans le cas de DayOtter, signifie qu’il faut prévoir 2 GB ou plus. Ne compilez jamais Cal.com depuis le code source sur une petite machine. Les propres instructions de build du projet demandent un heap Node de 16 GB. Utilisez plutôt l’image précompilée.

#scheduling#calendly#cal-com#self-hosted#booking