Guide de déploiement

Centrifugo sur VPS : serveur temps réel auto-hébergé

Déployer sur un VPS Cloud →

Tutoriel

Centrifugo sur VPS : serveur temps réel auto-hébergé

Self-hosting7 min de lecture3 étapes

Afficher une notification à l'instant où une commande est payée, faire vivre un chat, mettre à jour un tableau de bord sans recharger la page : tout cela demande une connexion ouverte en permanence entre le serveur et le navigateur. Les services comme Pusher ou Ably le font très bien, mais ils facturent chaque connexion et chaque message, et vos données passent par chez eux. Centrifugo est un serveur de messagerie temps réel open source (licence Apache-2.0), écrit en Go, qui fait le même travail sur votre propre VPS. Ce guide l'installe avec Docker Compose, le place derrière nginx en HTTPS, puis montre comment publier depuis votre backend et connecter un navigateur avec un jeton JWT.

Sommaire· Comment fonctionne Centrifugo1/13
  1. 01Comment fonctionne Centrifugo
  2. 02Ce que Centrifugo apporte
  3. 03Centrifugo face à un service hébergé
  4. 04Prérequis
  5. 05Installer Centrifugo avec Docker Compose
  6. 06Ne publiez jamais le port 8000 sur l'IP publique
  7. 07Placer Centrifugo derrière nginx
  8. 08Publier depuis votre backend
  9. 09Signer les jetons de connexion
  10. 10Ce qu'un client a le droit de faire
  11. 11Connecter un navigateur
  12. 12La console d'administration
  13. 13Montée en charge et mises à jour

Comment fonctionne Centrifugo

Centrifugo se place entre votre application et ses utilisateurs. Votre backend — Laravel, Django, Express, Rails ou autre — ne garde aucune connexion ouverte : il signe un jeton pour chaque utilisateur, puis publie des messages par un simple appel HTTP. Centrifugo, lui, maintient les connexions WebSocket des navigateurs et des applications mobiles, et livre chaque message aux abonnés du canal concerné.

Cette séparation a un avantage concret : votre application reste sans état et facile à déployer, et la partie temps réel tient dans un binaire Go unique qui consomme quelques dizaines de Mo de RAM au repos.

Ce que Centrifugo apporte

  • Connexions WebSocket — avec des SDK clients officiels pour JavaScript, Dart/Flutter, Swift, Java/Android, Go et Python.
  • API de publication — un POST HTTP avec l'en-tête X-API-Key, depuis n'importe quel langage.
  • Jetons JWT — votre backend décide qui se connecte et à quels canaux, Centrifugo vérifie la signature.
  • Abonnements côté serveur — la liste des canaux d'un utilisateur voyage dans son jeton.
  • Console d'administration — état du nœud, clients connectés et commandes d'API depuis le navigateur.
  • Défauts prudents — aucune connexion anonyme, aucune publication depuis le navigateur sans autorisation explicite.

Centrifugo face à un service hébergé

Faites défiler le tableau

Centrifugo sur VPSPusher, Ably
FacturationPrix du VPS, sans limite de messagesAu nombre de connexions et de messages
Où passent les donnéesSur votre serveurChez le fournisseur
Protocole clientWebSocket et SDK officielsWebSocket et SDK propriétaires
AuthentificationJWT signé par votre backendSignature propre au service
ExploitationÀ votre chargeAssurée par le fournisseur

Prérequis

Un VPS Ubuntu 24.04 avec 1 Go de RAM et 10 Go de disque, Docker et le plugin Compose installés, et un sous-domaine qui pointe vers le VPS, par exemple rt.example.com. Le HTTPS n'est pas optionnel : un site servi en HTTPS ne peut ouvrir que des connexions wss://, et votre clé d'API ne doit jamais circuler en clair.

Installer Centrifugo avec Docker Compose

  1. Générer les secrets

    Créez le répertoire de l'application et un fichier .env qui porte quatre secrets distincts : le mot de passe de la console, la clé qui signe ses sessions, la clé de l'API serveur et la clé HMAC des jetons clients.

    mkdir -p /opt/centrifugo && cd /opt/centrifugo
    {
      echo "ADMIN_PASSWORD=$(openssl rand -hex 12)"
      echo "SECRET_KEY=$(openssl rand -hex 24)"
      echo "ENCRYPTION_KEY=$(openssl rand -hex 16)"
      echo "ENCRYPTION_KEY_HEX64=$(openssl rand -hex 32)"
    } > .env
    chmod 600 .env
  2. Écrire le fichier docker-compose.yml

    Le port est publié sur la boucle locale uniquement : seul nginx y accède. Remplacez https://app.example.com par l'adresse de votre site.

    services:
      centrifugo:
        image: centrifugo/centrifugo:v6.10.2
        restart: unless-stopped
        command: ["centrifugo"]
        ports:
          - "127.0.0.1:8000:8000"
        environment:
          CENTRIFUGO_ADMIN_ENABLED: "true"
          CENTRIFUGO_ADMIN_PASSWORD: "${ADMIN_PASSWORD}"
          CENTRIFUGO_ADMIN_SECRET: "${SECRET_KEY}"
          CENTRIFUGO_HTTP_API_KEY: "${ENCRYPTION_KEY}"
          CENTRIFUGO_CLIENT_TOKEN_HMAC_SECRET_KEY: "${ENCRYPTION_KEY_HEX64}"
          CENTRIFUGO_CLIENT_ALLOWED_ORIGINS: "https://app.example.com"
          CENTRIFUGO_HEALTH_ENABLED: "true"
        ulimits:
          nofile:
            soft: 65535
            hard: 65535
  3. Démarrer et vérifier

    Lancez le conteneur et interrogez le point de santé ; il doit répondre {}.

    docker compose up -d
    curl -fsS http://127.0.0.1:8000/health

Ne publiez jamais le port 8000 sur l'IP publique

Le même port sert les connexions clients, l'API serveur et la console d'administration. Gardez-le sur 127.0.0.1 et passez toujours par le reverse proxy HTTPS. Et ne mettez jamais ENCRYPTION_KEY ni ENCRYPTION_KEY_HEX64 dans du code envoyé au navigateur : la première permet de publier sur n'importe quel canal, la seconde de fabriquer des jetons pour n'importe quel utilisateur.

Placer Centrifugo derrière nginx

Une connexion WebSocket commence par une requête HTTP qui demande un changement de protocole. nginx doit transmettre cette demande, et ne pas couper une connexion qui reste silencieuse quelques minutes. Dans le bloc server de votre sous-domaine, avec un certificat Let's Encrypt :

location / {
    proxy_pass http://127.0.0.1:8000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_read_timeout 3600s;
}

Après nginx -t et un rechargement, https://rt.example.com affiche l'écran de connexion de la console.

Publier depuis votre backend

Publier, c'est envoyer un objet JSON à un canal. N'importe quel langage capable de faire une requête HTTP convient :

curl -X POST https://rt.example.com/api/publish \
  -H "X-API-Key: $ENCRYPTION_KEY" \
  -d '{"channel": "commandes", "data": {"id": 1042, "statut": "payee"}}'

La réponse {"result":{}} confirme que le message est accepté. Sans en-tête X-API-Key, ou avec une mauvaise clé, Centrifugo répond 401.

Signer les jetons de connexion

Un navigateur ne se connecte qu'avec un jeton JWT signé par votre backend avec ENCRYPTION_KEY_HEX64. La revendication sub porte l'identifiant de l'utilisateur, exp la date d'expiration, et channels la liste des canaux auxquels il est abonné d'office. Exemple en Python :

import time, jwt  # pip install pyjwt

def centrifugo_token(user_id: str) -> str:
    claims = {"sub": user_id, "exp": int(time.time()) + 3600, "channels": ["commandes"]}
    return jwt.encode(claims, ENCRYPTION_KEY_HEX64, algorithm="HS256")

Exposez cette fonction derrière une route authentifiée de votre application : seul un utilisateur connecté chez vous doit pouvoir obtenir un jeton.

Ce qu'un client a le droit de faire

Les réglages de cette installation sont volontairement fermés. Un navigateur ne peut ni s'abonner de lui-même à un canal, ni y publier : il reçoit uniquement les canaux listés dans la revendication channels de son jeton. C'est votre backend qui décide, à chaque émission de jeton, qui écoute quoi — un client ne voit que ses propres commandes, un agent du support que la file de son équipe.

Pour un chat, la publication passe donc elle aussi par votre backend : le navigateur envoie le message à votre application, qui le valide, l'enregistre en base, puis le publie par l'API. Ce détour coûte quelques millisecondes et vous garde la main sur la modération et l'historique.

Donnez enfin aux jetons une durée courte, une heure par exemple. Plutôt que de passer un jeton figé, laissez le SDK en redemander un à votre application quand il expire :

const client = new Centrifuge('wss://rt.example.com/connection/websocket', {
  getToken: async () => {
    const res = await fetch('/realtime/token', { credentials: 'include' });
    return (await res.json()).token;
  },
});

La route /realtime/token est celle de votre application ; elle vérifie la session de l'utilisateur avant de signer quoi que ce soit.

Connecter un navigateur

Côté client, le SDK officiel centrifuge (npm) ouvre la connexion et rend les messages :

import { Centrifuge } from 'centrifuge';

const client = new Centrifuge('wss://rt.example.com/connection/websocket', {
  token: tokenFromYourBackend,
});
client.on('publication', (ctx) => console.log(ctx.channel, ctx.data));
client.connect();

Si la connexion échoue, regardez d'abord les journaux (docker compose logs centrifugo). Le message « request Origin is not authorized » signifie que l'origine de votre site manque dans CENTRIFUGO_CLIENT_ALLOWED_ORIGINS ; « invalid token » désigne un jeton mal signé ou expiré.

La console d'administration

Ouvrez https://rt.example.com et saisissez ADMIN_PASSWORD : la console ne demande pas d'identifiant. Elle affiche la version du nœud, le nombre de clients et d'utilisateurs connectés, et permet d'envoyer des commandes d'API — publier un message de test, lister les canaux actifs — sans écrire de code. C'est l'outil le plus rapide pour vérifier qu'un message part bien avant de chercher le défaut côté navigateur.

Montée en charge et mises à jour

Ce guide utilise le moteur mémoire : un seul nœud, sans dépendance. Il convient à la plupart des applications, et un VPS modeste tient déjà un grand nombre de connexions simultanées, d'où la limite de fichiers ouverts relevée dans le docker-compose.yml. Le jour où un nœud ne suffit plus, Centrifugo sait répartir la charge entre plusieurs nœuds reliés par Redis. Pour mettre à jour, changez le tag de l'image après avoir lu les notes de version, puis relancez docker compose pull && docker compose up -d ; les connexions se rétablissent seules, les SDK clients se reconnectant automatiquement.

Votre serveur temps réel sur votre VPS

Un VPS ServOrbit Ubuntu 24.04 avec 1 Go de RAM suffit pour démarrer Centrifugo. Installation en un clic depuis le Marketplace, HTTPS et WebSocket sur votre domaine ou sur le sous-domaine gratuit du VPS, mot de passe et clés générés pour vous.

Besoin d'aide ?

Parcourez notre centre d'aide et notre FAQ, ou contactez notre équipe — rappel, WhatsApp ou e-mail. Support en français, anglais et arabe.

Écrire sur WhatsApps'ouvre dans un nouvel onglet