[{"data":1,"prerenderedAt":191},["ShallowReactive",2],{"seo-verification":3,"blog-self-host-centrifugo-vps-fr":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-self-host-centrifugo-vps-fr",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"noindex":20,"publishedAt":21,"updatedAt":22,"category":23,"categories":28,"featuredImage":30,"bgImage":31,"posterImage":32,"relatedSolution":33,"intro":36,"sections":37,"ctaTitle":120,"ctaBody":121,"ctaButton":122,"ctaUrl":123,"relatedPosts":124},569,"self-host-centrifugo-vps",{"fr":10,"en":12,"ar":13,"es":14},"self-host-centrifugo-vps-real-time-server","استضافة-centrifugo-على-vps-خادم-زمن-حقيقي","autoalojar-centrifugo-vps-servidor-tiempo-real","Centrifugo sur VPS : serveur temps réel auto-hébergé","Installez Centrifugo sur un VPS : un serveur temps réel open source pour pousser des messages WebSocket depuis votre backend, avec jetons JWT et API.",7,0,false,true,"2026-11-07T00:00:00+00:00","2026-11-08T01:13:02+00:00",{"id":17,"name":24,"slug":25,"color":26,"icon":27},"Self-hosting","self-hosting","bg-indigo-500\u002F10 text-indigo-400","cloud",[29],{"id":17,"name":24,"slug":25,"color":26,"icon":27},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fself-host-centrifugo-vps-poster.svg",{"categorySlug":34,"appSlug":35},"developpement","centrifugo","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.",[38,42,52,79,82,95,99,102,105,108,111,114,117],{"type":39,"title":40,"body":41},"h2","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é.\n\nCette 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.",{"type":43,"title":44,"items":45},"ul","Ce que Centrifugo apporte",[46,47,48,49,50,51],"**Connexions WebSocket** — avec des SDK clients officiels pour JavaScript, Dart\u002FFlutter, Swift, Java\u002FAndroid, 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.",{"type":53,"title":54,"headers":55,"rows":58},"comparison","Centrifugo face à un service hébergé",[5,56,57],"Centrifugo sur VPS","Pusher, Ably",[59,63,67,71,75],[60,61,62],"Facturation","Prix du VPS, sans limite de messages","Au nombre de connexions et de messages",[64,65,66],"Où passent les données","Sur votre serveur","Chez le fournisseur",[68,69,70],"Protocole client","WebSocket et SDK officiels","WebSocket et SDK propriétaires",[72,73,74],"Authentification","JWT signé par votre backend","Signature propre au service",[76,77,78],"Exploitation","À votre charge","Assurée par le fournisseur",{"type":39,"title":80,"body":81},"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:\u002F\u002F`, et votre clé d'API ne doit jamais circuler en clair.",{"type":83,"title":84,"steps":85},"steps","Installer Centrifugo avec Docker Compose",[86,89,92],{"title":87,"body":88},"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.\n```bash\nmkdir -p \u002Fopt\u002Fcentrifugo && cd \u002Fopt\u002Fcentrifugo\n{\n  echo \"ADMIN_PASSWORD=$(openssl rand -hex 12)\"\n  echo \"SECRET_KEY=$(openssl rand -hex 24)\"\n  echo \"ENCRYPTION_KEY=$(openssl rand -hex 16)\"\n  echo \"ENCRYPTION_KEY_HEX64=$(openssl rand -hex 32)\"\n} > .env\nchmod 600 .env\n```",{"title":90,"body":91},"Écrire le fichier docker-compose.yml","Le port est publié sur la boucle locale uniquement : seul nginx y accède. Remplacez `https:\u002F\u002Fapp.example.com` par l'adresse de votre site.\n```yaml\nservices:\n  centrifugo:\n    image: centrifugo\u002Fcentrifugo:v6.10.2\n    restart: unless-stopped\n    command: [\"centrifugo\"]\n    ports:\n      - \"127.0.0.1:8000:8000\"\n    environment:\n      CENTRIFUGO_ADMIN_ENABLED: \"true\"\n      CENTRIFUGO_ADMIN_PASSWORD: \"${ADMIN_PASSWORD}\"\n      CENTRIFUGO_ADMIN_SECRET: \"${SECRET_KEY}\"\n      CENTRIFUGO_HTTP_API_KEY: \"${ENCRYPTION_KEY}\"\n      CENTRIFUGO_CLIENT_TOKEN_HMAC_SECRET_KEY: \"${ENCRYPTION_KEY_HEX64}\"\n      CENTRIFUGO_CLIENT_ALLOWED_ORIGINS: \"https:\u002F\u002Fapp.example.com\"\n      CENTRIFUGO_HEALTH_ENABLED: \"true\"\n    ulimits:\n      nofile:\n        soft: 65535\n        hard: 65535\n```",{"title":93,"body":94},"Démarrer et vérifier","Lancez le conteneur et interrogez le point de santé ; il doit répondre `{}`.\n```bash\ndocker compose up -d\ncurl -fsS http:\u002F\u002F127.0.0.1:8000\u002Fhealth\n```",{"type":96,"title":97,"body":98},"tip","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.",{"type":39,"title":100,"body":101},"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 :\n```nginx\nlocation \u002F {\n    proxy_pass http:\u002F\u002F127.0.0.1:8000;\n    proxy_http_version 1.1;\n    proxy_set_header Upgrade $http_upgrade;\n    proxy_set_header Connection \"upgrade\";\n    proxy_set_header Host $host;\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    proxy_read_timeout 3600s;\n}\n```\nAprès `nginx -t` et un rechargement, `https:\u002F\u002Frt.example.com` affiche l'écran de connexion de la console.",{"type":39,"title":103,"body":104},"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 :\n```bash\ncurl -X POST https:\u002F\u002Frt.example.com\u002Fapi\u002Fpublish \\\n  -H \"X-API-Key: $ENCRYPTION_KEY\" \\\n  -d '{\"channel\": \"commandes\", \"data\": {\"id\": 1042, \"statut\": \"payee\"}}'\n```\nLa 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`.",{"type":39,"title":106,"body":107},"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 :\n```python\nimport time, jwt  # pip install pyjwt\n\ndef centrifugo_token(user_id: str) -> str:\n    claims = {\"sub\": user_id, \"exp\": int(time.time()) + 3600, \"channels\": [\"commandes\"]}\n    return jwt.encode(claims, ENCRYPTION_KEY_HEX64, algorithm=\"HS256\")\n```\nExposez cette fonction derrière une route authentifiée de votre application : seul un utilisateur connecté chez vous doit pouvoir obtenir un jeton.",{"type":39,"title":109,"body":110},"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.\n\nPour 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.\n\nDonnez 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 :\n```javascript\nconst client = new Centrifuge('wss:\u002F\u002Frt.example.com\u002Fconnection\u002Fwebsocket', {\n  getToken: async () => {\n    const res = await fetch('\u002Frealtime\u002Ftoken', { credentials: 'include' });\n    return (await res.json()).token;\n  },\n});\n```\nLa route `\u002Frealtime\u002Ftoken` est celle de votre application ; elle vérifie la session de l'utilisateur avant de signer quoi que ce soit.",{"type":39,"title":112,"body":113},"Connecter un navigateur","Côté client, le SDK officiel `centrifuge` (npm) ouvre la connexion et rend les messages :\n```javascript\nimport { Centrifuge } from 'centrifuge';\n\nconst client = new Centrifuge('wss:\u002F\u002Frt.example.com\u002Fconnection\u002Fwebsocket', {\n  token: tokenFromYourBackend,\n});\nclient.on('publication', (ctx) => console.log(ctx.channel, ctx.data));\nclient.connect();\n```\nSi 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é.",{"type":39,"title":115,"body":116},"La console d'administration","Ouvrez `https:\u002F\u002Frt.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.",{"type":39,"title":118,"body":119},"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.","Installer Centrifugo","\u002Fapplications\u002Fdeveloppement\u002Fcentrifugo",[125,150,173],{"id":126,"slug":127,"slugs":128,"title":132,"excerpt":133,"readTime":134,"views":135,"isPinned":19,"noindex":19,"publishedAt":136,"updatedAt":137,"category":138,"categories":144,"featuredImage":30,"bgImage":31,"posterImage":146,"relatedSolution":147},194,"self-host-ntfy-vps",{"fr":127,"en":129,"ar":130,"es":131},"self-host-ntfy-on-a-vps-push-notifications-for-scripts-and-cicd","استضافة-ntfy-على-vps-إشعارات-فورية-من-سكريبتاتك-وcicd","autoalojar-ntfy-en-un-vps","Héberger ntfy sur un VPS : notifications push pour vos scripts","Déployez ntfy sur votre VPS et envoyez des notifications push depuis n'importe quel script, cron ou pipeline CI\u002FCD avec un simple curl — sans SaaS ni clé d'API.",16,2,"2026-07-28T00:00:00+00:00","2026-11-04T16:30:26+00:00",{"id":139,"name":140,"slug":141,"color":142,"icon":143},8,"Sécurité & Monitoring","securite-monitoring","bg-rose-500\u002F10 text-rose-400","security",[145],{"id":139,"name":140,"slug":141,"color":142,"icon":143},"\u002Fblog\u002Fcovers\u002Fself-host-ntfy-vps-poster.svg",{"categorySlug":148,"appSlug":149},"monitoring","ntfy",{"id":151,"slug":152,"slugs":153,"title":157,"excerpt":158,"readTime":159,"views":18,"isPinned":19,"noindex":19,"publishedAt":160,"updatedAt":161,"category":162,"categories":168,"featuredImage":30,"bgImage":31,"posterImage":170,"relatedSolution":171},58,"heberger-redis-vps",{"fr":152,"en":154,"ar":155,"es":156},"hosting-redis-on-a-vps","استضافة-redis-على-خادم-vps","alojar-redis-en-un-vps","Héberger Redis sur un VPS : guide complet","Déployez Redis sur votre VPS Cloud : prérequis RAM\u002FCPU, sécurité (ACL, TLS), persistance RDB\u002FAOF, dépannage et haute disponibilité.",10,"2026-04-23T00:00:00+00:00","2026-09-08T21:59:59+00:00",{"id":163,"name":164,"slug":165,"color":166,"icon":167},6,"Bases de données","bases-de-donnees","bg-teal-500\u002F10 text-teal-400","database",[169],{"id":163,"name":164,"slug":165,"color":166,"icon":167},"\u002Fblog\u002Fcovers\u002Fheberger-redis-vps-poster.svg",{"categorySlug":165,"appSlug":172},"redis-stack",{"id":174,"slug":175,"slugs":176,"title":180,"excerpt":181,"readTime":182,"views":18,"isPinned":19,"noindex":19,"publishedAt":183,"updatedAt":184,"category":185,"categories":186,"featuredImage":30,"bgImage":31,"posterImage":188,"relatedSolution":189},60,"heberger-supabase-vps",{"fr":175,"en":177,"ar":178,"es":179},"hosting-supabase-on-a-vps","استضافة-supabase-على-خادم-vps","alojar-supabase-en-un-vps","Héberger Supabase sur un VPS en 2026","Self-hostez Supabase sur votre VPS : Postgres, Auth, Storage et API REST derrière Envoy. Migration PG 15→17, Kong→Envoy, CVE GoTrue.",15,"2026-04-21T00:00:00+00:00","2026-11-08T01:13:14+00:00",{"id":163,"name":164,"slug":165,"color":166,"icon":167},[187],{"id":163,"name":164,"slug":165,"color":166,"icon":167},"\u002Fblog\u002Fcovers\u002Fheberger-supabase-vps-poster.svg",{"categorySlug":165,"appSlug":190},"supabase",1794100995948]