Héberger soi-même Rocket.Chat pour le clavardage d'équipe
Suivez ça sur votre propre serveur. Commencer gratuitement, sans carte
La tarification par siège de Slack augmente avec le nombre d’employés, pas avec la quantité réelle de clavardage de votre équipe, et dès que chaque message doit rester sur une infrastructure que vous contrôlez, un service SaaS hébergé cesse carrément d’être une option. Rocket.Chat est une plateforme de clavardage d’équipe open source qui fait le même travail, canaux, messages directs, partage de fichiers, recherche, et que vous hébergez vous-même. La seule chose qui rend son auto-hébergement plus difficile que la plupart des outils de clavardage, c’est qu’elle a besoin de MongoDB configuré en replica set, pas une base de données autonome ordinaire, parce que Rocket.Chat dépend des change streams de MongoDB pour pousser les messages aux clients connectés en temps réel. À la fin de ce guide, vous aurez une instance Rocket.Chat fonctionnelle sur votre propre serveur Hetzner, derrière HTTPS, avec ce replica set correctement initialisé, des sauvegardes et une façon sécuritaire de la mettre à niveau plus tard.
Ce qu’il vous faut
- Un compte Hetzner Cloud et un serveur. Rocket.Chat avec un replica set MongoDB a besoin de plus de marge que les instances les plus petites, donc ce guide utilise le CX33 (4 vCPU, 8 Go de mémoire, 80 Go NVMe), affiché à 8,99 €/mois hors TVA. Vérifiez le prix actuel dans la console Hetzner Cloud avant de commander, puisque les gammes et les prix changent.
- Un nom de domaine (ou un sous-domaine d’un domaine que vous possédez déjà), avec accès à ses paramètres DNS.
- Une paire de clés SSH sur votre machine (
ssh-keygen -t ed25519si vous n’en avez pas déjà une). - Docker et le plugin Docker Compose installés sur le serveur (couvert à l’étape 2).
- Un terminal et environ vingt minutes, surtout en attente du DNS et de la synchronisation initiale.
Étape 1 : créer le serveur et pointer un domaine vers lui
Dans la console Hetzner Cloud, ouvrez ou créez un projet, puis choisissez Add Server. Choisissez un emplacement : Nuremberg, Falkenstein ou Helsinki gardent vos données dans l’UE, tandis qu’Ashburn, Hillsboro ou Singapour sont aussi offerts si votre équipe est ailleurs. Choisissez Ubuntu 24.04 comme image, puis sous le type de serveur choisissez le vCPU partagé CX33 (4 vCPU, 8 Go de mémoire, 80 Go NVMe). Sous les clés SSH, ajoutez la clé publique de votre machine au lieu de vous fier à un mot de passe généré, puis créez le serveur.
Une fois qu’il démarre, notez son adresse IPv4 publique et connectez-vous pour confirmer l’accès :
ssh root@YOUR_SERVER_IP
Vous devriez atterrir dans un shell root avec la bannière de bienvenue Ubuntu, sans invite de mot de passe.
Dans les paramètres DNS de votre domaine, ajoutez un enregistrement A pointant un sous-domaine, par exemple chat.votredomaine.com, vers cette IP :
Type: A
Name: chat
Value: <IP de votre serveur>
TTL: 300
La propagation DNS peut prendre de quelques minutes à quelques heures. Confirmez-le depuis votre propre machine avant de continuer, puisque la demande de certificat de Caddy à l’étape 5 en dépend :
dig chat.votredomaine.com +short
Vous devriez voir l’IP de votre serveur retournée.
Étape 2 : installer Docker
Connectez-vous en SSH au serveur et installez Docker Engine ainsi que le plugin Compose :
apt-get update
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
systemctl enable --now docker
Hetzner ne place pas de pare-feu devant un nouveau serveur par défaut, donc verrouillez l’hôte avec ufw :
ufw allow OpenSSH
ufw allow 80
ufw allow 443
ufw --force enable
Vérifiez l’installation :
docker --version
docker compose version
Vous devriez voir une version de Docker et une version de Compose affichées, pas une erreur « command not found ».
Étape 3 : organiser le projet et ses secrets
Créez un répertoire pour la pile et un fichier .env pour garder le domaine et tout ce qui ne devrait pas se retrouver dans le fichier compose lui-même :
mkdir -p /opt/rocketchat && cd /opt/rocketchat
cat > .env <<'EOF'
DOMAIN=chat.votredomaine.com
EOF
chmod 600 .env
Rocket.Chat ne prend pas un nom d’utilisateur ou un mot de passe administrateur comme configuration de conteneur, contrairement à certaines applications. Le premier compte administrateur est créé plus tard, par l’assistant de configuration propre à l’application, donc il n’y a aucun identifiant à générer ou à stocker à cette étape au-delà du domaine lui-même.
Étape 4 : écrire le fichier Docker Compose
C’est ici que l’exigence du replica set entre vraiment en jeu. Le service mongo doit démarrer mongod avec --replSet rs0, puis vérifier si un replica set est déjà initialisé, et sinon, en initier un avec lui-même comme seul membre. C’est une commande shell composée, pas un simple appel de binaire, donc elle doit s’exécuter dans un shell plutôt que comme arguments directs de mongod.
Créez docker-compose.yml :
services:
rocket-chat:
image: rocketchat/rocket.chat:8.5.4
restart: unless-stopped
environment:
- PORT=3000
- ROOT_URL=https://${DOMAIN}
- DEPLOY_METHOD=docker
- MONGO_URL=mongodb://mongo:27017/rocketchat?replicaSet=rs0
- MONGO_OPLOG_URL=mongodb://mongo:27017/local?replicaSet=rs0
volumes:
- rocketchat_uploads:/app/uploads
depends_on:
- mongo
networks:
- rocketchat-net
mongo:
image: mongodb/mongodb-community-server:8.0-ubi8
restart: unless-stopped
command: ["bash", "-c", "mongod --replSet rs0 --bind_ip_all --fork --logpath /data/db/mongod.log && mongosh --quiet --eval \"try { rs.status().ok } catch (e) { rs.initiate({_id: 'rs0', members: [{_id: 0, host: 'mongo:27017'}]}) }\" && tail -f /data/db/mongod.log"]
volumes:
- mongo_data:/data/db
networks:
- rocketchat-net
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
environment:
- DOMAIN=${DOMAIN}
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
depends_on:
- rocket-chat
networks:
- rocketchat-net
networks:
rocketchat-net:
volumes:
rocketchat_uploads:
mongo_data:
caddy_data:
caddy_config:
Quelques points méritent d’être expliqués :
- La
commanddemongofait trois choses en séquence : démarrermongoden arrière-plan (--fork) lié à toutes les interfaces avec la réplication activée, puis exécutermongoshpour vérifierrs.status().ok, en interceptant l’erreur que cet appel lève sur une base de données fraîche et en appelantrs.initiate()avec ce conteneur comme seul membre ders0si c’est le cas, et finalement faire untail -fdu fichier journal pour que le conteneur ait un processus au premier plan qui le garde vivant. À chaque redémarrage après le premier,rs.status().okréussit déjà, doncrs.initiate()est ignoré et le conteneur démarre simplement. - Ni
rocket-chatnimongon’ont d’entréesecurity_opt: ["no-new-privileges:true"], et c’est délibéré, pas un oubli. Le point d’entrée de MongoDB abandonne les privilèges root en se réexécutant lui-même comme sous-processus, et cette réexécution a besoin de la capacité d’obtenir de nouveaux privilèges. Ajouter le drapeau de durcissement habituel ici brisemongod --forkavec un « child process failed, exited with 1 » générique et aucune erreur plus claire dans le journal. - Les deux images sont épinglées à des étiquettes exactes,
rocket.chat:8.5.4etmongodb-community-server:8.0-ubi8, plutôt quelatest. Un serveur de clavardage qui change silencieusement de comportement de base de données à un redémarrage n’est pas quelque chose que vous voulez découvrir en pleine journée de travail. - Seul Caddy publie des ports vers l’hôte. Rocket.Chat et MongoDB ne sont accessibles que sur le réseau Docker interne.
Vérifiez que le fichier s’analyse correctement :
docker compose config
Vous devriez voir la configuration entièrement résolue affichée sans ligne d’erreur.
Étape 5 : écrire le Caddyfile et tout démarrer
Créez Caddyfile dans le même répertoire :
{$DOMAIN} {
reverse_proxy rocket-chat:3000
}
Caddy demande automatiquement un certificat TLS gratuit à Let’s Encrypt pour votre domaine, tant que le DNS pointe déjà vers ce serveur et que les ports 80 et 443 sont accessibles depuis Internet, ce que les étapes 1 et 2 ont déjà mis en place.
Démarrez la pile :
docker compose up -d
Observez les journaux pendant que Mongo démarre :
docker compose logs -f mongo
Le premier démarrage prend plus de temps que les redémarrages suivants, puisqu’il doit initialiser le replica set avant que Rocket.Chat puisse s’y connecter. Une fois que c’est stabilisé, vérifiez que Caddy a obtenu son certificat :
docker compose logs -f caddy
Vous devriez voir une ligne mentionnant un certificat obtenu pour votre domaine. Confirmez que tout est démarré :
docker compose ps
Les trois services devraient afficher Up.
Étape 6 : créer le premier compte administrateur
Visitez https://chat.votredomaine.com dans un navigateur. L’assistant de configuration propre à Rocket.Chat se charge, demandant un nom d’organisation, puis un compte administrateur, un courriel et un mot de passe. C’est le processus de premier démarrage de Rocket.Chat, pas quelque chose que le fichier compose configure pour vous, donc il n’y a rien à scripter ici au-delà de le compléter une fois. Ensuite, l’assistant propose quelques étapes facultatives, des paramètres d’inscription, une invite de fédération, que vous pouvez sauter ou configurer à votre guise; rien de tout cela n’empêche l’instance de fonctionner.
Étape 7 : sauvegarder la base de données et le volume de téléversements
Deux choses doivent être sauvegardées : les données MongoDB (canaux, messages, utilisateurs, paramètres) et le volume rocketchat_uploads (fichiers partagés dans le clavardage). Un mongodump contre le conteneur en marche, redirigé directement vers une archive compressée :
docker compose exec -T mongo mongodump --archive --gzip > rocketchat-backup-$(date +%F).gz
Placez ça dans une tâche cron quotidienne, et copiez le résultat ailleurs que sur ce serveur, un compartiment de stockage objet, une autre machine, n’importe où qui n’est pas cette boîte. Une sauvegarde qui ne vit que sur le serveur qu’elle protège ne survit pas au mode de défaillance qui met réellement un serveur hors service.
Pour le volume de téléversements :
docker run --rm -v rocketchat_rocketchat_uploads:/data -v $(pwd):/backup alpine \
tar czf /backup/rocketchat-uploads-backup.tar.gz -C /data .
Gardez les deux fichiers quelque part avec accès contrôlé; une sauvegarde d’historique de messages reste de vraies données utilisateur.
Étape 8 : mettre à niveau de façon délibérée
Les deux images sont épinglées, donc une mise à niveau est un choix conscient, pas quelque chose qui arrive lors d’un redémarrage de routine. Avant de changer l’une ou l’autre des étiquettes, lisez les notes de version propres à Rocket.Chat pour chaque version entre ce que vous faites tourner et ce vers quoi vous allez. Rocket.Chat, comme plusieurs applications avec un long historique, peut exiger de passer par des versions majeures intermédiaires en séquence plutôt que de sauter directement d’une vieille version vers la plus récente, donc vérifiez ça avant de supposer qu’un seul saut est sécuritaire.
Changez l’étiquette dans docker-compose.yml :
image: rocketchat/rocket.chat:8.6.0
Puis :
docker compose pull
docker compose up -d
Vérifiez les journaux pour un démarrage propre sans erreur de migration, et confirmez que vos canaux et votre historique de messages sont intacts après vous être reconnecté. Si une migration tourne vraiment mal, votre sauvegarde de l’étape 7 est la façon de revenir à la version précédente; restaurez-la contre l’ancienne étiquette d’image avant de décider quoi faire ensuite.
Le raccourci : le faire avec Railyard
Tout ce qui précède, un replica set MongoDB dédié correctement initialisé, le volume de téléversements, HTTPS déjà configuré, est aussi disponible comme déploiement en un clic, mais puisque c’est une pile à plusieurs services plutôt qu’un seul conteneur, le lien ne la déploie pas directement comme le ferait un modèle d’application à un seul conteneur :
https://app.railyard.run/deploy?stack=rocket-chat
Ce lien ouvre le catalogue de modèles au lieu de déployer directement, puisqu’une pile a besoin que vous confirmiez ses services avant qu’elle ne provisionne quoi que ce soit. Choisissez Rocket.Chat dans le catalogue de modèles à partir de là. Railyard configure la même exigence de replica set que ce guide parcourt à la main, le même volume de téléversements persistant, et HTTPS sur votre domaine, sans que vous ayez à écrire le fichier compose ou la commande shell à l’intérieur du conteneur Mongo vous-même.
Bouton de déploiement explique comment fonctionnent le lien ?stack= et le flux du catalogue de modèles si vous voulez comprendre ou en intégrer un ailleurs. Bases de données et sauvegardes couvre comment les sauvegardes fonctionnent à travers les modèles en général, pas seulement celui-ci. Si vous partez de Railyard avant de vous décider sur Rocket.Chat précisément, le guide de démarrage couvre les bases. Le forfait gratuit de Railyard couvre un serveur plus un serveur de base de données et trois applications sans carte requise, Pro est à 19 $/mois par équipe, et Team est à 49 $/mois par équipe.
Dépannage
Le replica set ne s’initialise jamais, ou rs.status().ok continue d’échouer. Vérifiez docker compose logs mongo pour l’erreur réelle de l’appel rs.initiate(). La cause la plus commune est que le nom d’hôte dans members ne correspond pas à ce que le service rocket-chat résout réellement; dans ce fichier compose, cet hôte est le nom de service mongo, donc si vous avez renommé le service, la valeur host: à l’intérieur de la commande doit lui correspondre exactement.
Mongo échoue à démarrer avec mongod --fork: "child process failed, exited with 1". C’est presque toujours security_opt: ["no-new-privileges:true"] ajouté au service mongo, habituellement en appliquant une passe générale de durcissement de conteneurs à tous les services d’un fichier compose sans exception pour celui-ci. Le point d’entrée de MongoDB se réexécute lui-même comme sous-processus pour abandonner les privilèges root, et cette réexécution a besoin de la capacité d’obtenir de nouveaux privilèges; le drapeau de durcissement bloque exactement ça. Retirez-le spécifiquement du service mongo.
Rocket.Chat se charge mais chaque lien, avatar ou redirection pointe vers la mauvaise adresse. C’est une incohérence de ROOT_URL. Elle doit être exactement l’URL HTTPS à laquelle vous visitez réellement l’instance, y compris le schéma; si elle est configurée en http:// au lieu de https://, ou vers un nom d’hôte différent de celui que Caddy sert, vous verrez des boucles de redirection dans le navigateur ou des URL de ressources brisées dans le code source de la page.
Caddy n’obtient jamais de certificat, ou le navigateur affiche un avertissement de certificat. C’est presque toujours le DNS, pas Caddy. Lancez dig chat.votredomaine.com +short et confirmez qu’il retourne l’IP de ce serveur, pas une ancienne ou rien du tout. Let’s Encrypt a aussi besoin que le port 80 soit accessible depuis Internet pour l’étape de validation initiale, donc vérifiez que votre pare-feu permet le trafic entrant sur le 80, pas seulement le 443.
Mongo se fait tuer ou le serveur devient non réactif en utilisation normale. Un replica set, même à un seul nœud, garde plus de choses en mémoire qu’une instance Mongo autonome ordinaire, et Rocket.Chat lui-même n’est pas un processus léger. Si vous êtes sur un serveur plus petit que le CX33 utilisé dans ce guide, c’est la première chose à vérifier avec docker stats avant de supposer que quelque chose d’autre cloche; monter d’une taille est habituellement la vraie solution, pas un drapeau d’ajustement.
FAQ
Puis-je sauter le replica set et faire tourner Mongo comme une instance autonome ordinaire? Non. Rocket.Chat utilise les change streams de MongoDB, qui n’existent que sur un replica set, pour pousser les nouveaux messages et les mises à jour de présence aux clients connectés sans sondage. Un Mongo autonome laissera Rocket.Chat démarrer, mais les mises à jour en temps réel ne fonctionneront pas correctement, donc ce n’est pas une étape de durcissement facultative que vous pouvez sauter pour une empreinte plus petite.
Est-ce le Rocket.Chat classique ou la version en microservices? C’est le monolithe classique, un seul conteneur rocket-chat qui parle à une seule base de données, ce qui convient à la plupart des tailles d’équipe et est le plus simple à opérer vous-même. Rocket.Chat publie aussi une version en microservices pour les très grands déploiements; sa propre documentation couvre ce chemin si vous avez un jour besoin de dépasser ce qu’un seul conteneur peut gérer.
Combien ça coûte à faire tourner? Le serveur est à 8,99 €/mois hors TVA pour le CX33 utilisé dans ce guide. Rocket.Chat lui-même est un logiciel libre et gratuit sans frais par siège; le coût, c’est la boîte sur laquelle il tourne, pas une licence.
Qu’arrive-t-il si une migration échoue pendant une mise à niveau? Le démarrage de Rocket.Chat exécute ses propres migrations internes contre la base de données au démarrage. Si l’une échoue, les journaux du conteneur le montreront clairement plutôt que l’application démarrant silencieusement à moitié migrée. Vos options à ce moment sont de restaurer la sauvegarde de l’étape 7 contre l’ancienne étiquette d’image, ou de lire l’erreur de migration spécifique et les notes de version correspondantes avant de réessayer; ne réessayez pas à l’aveugle contre le même état de base de données.
Ai-je besoin d’un service de courriel séparé pour inviter des utilisateurs? Pas pour faire fonctionner l’instance; le compte administrateur de l’étape 6 peut créer et inviter des utilisateurs directement depuis le panneau d’administration sans courriel sortant configuré. Vous voudrez éventuellement configurer SMTP pour les réinitialisations de mot de passe et les courriels de notification, mais ce n’est pas un obstacle pour un premier déploiement fonctionnel.
Une instance Rocket.Chat auto-hébergée représente une quantité modeste de configuration pour quelque chose que vous laisserez probablement tourner pendant des années : l’historique de messages de votre équipe reste sur un serveur que vous contrôlez, avec une routine de sauvegarde et une voie de mise à niveau qui ne dépendent du calendrier de personne d’autre.
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.