← Blogue

Héberger Chatwoot soi-même avec Postgres, Redis et Sidekiq

Railyard

11 avril 2026 · 10 min de lecture

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

Chatwoot offre une boîte de réception partagée et un widget de clavardage en direct sans facture SaaS par agent, mais le projet lui-même compte quatre pièces mobiles : un processus web Rails, un worker Sidekiq pour les tâches en arrière-plan, Postgres et Redis. Si l’une de ces pièces est mal configurée (un FRONTEND_URL périmé, un worker incapable de joindre Redis, un certificat qui n’est jamais émis), vous obtenez une page de connexion qui tourne dans le vide au lieu d’une boîte de réception fonctionnelle. À la fin de ce guide, les quatre services tourneront sur votre propre serveur, derrière le HTTPS, avec des sauvegardes et une procédure de mise à jour que vous pourrez réellement répéter.

Ce qu’il vous faut

  • Un serveur avec au moins 4 vCPU et 8 Go de RAM. La documentation officielle d’auto-hébergement de Chatwoot indique 2 cœurs / 4 Go comme minimum absolu, mais ce chiffre ne concerne que le processus web seul. Une fois le worker Sidekiq, Postgres et Redis ajoutés sur la même machine, leur documentation recommande plutôt 4 cœurs et plus, et 8 Go et plus. Un Hetzner CX33 (4 vCPU, 8 Go de RAM, 80 Go NVMe) correspond à cette recommandation et coûte actuellement 8,99 €/mois hors TVA.
  • Ubuntu 22.04 ou plus récent, avec un accès root ou sudo.
  • Un nom de domaine vers lequel vous pouvez pointer un enregistrement A (ce guide utilise chat.example.com).
  • Optionnel mais recommandé : des identifiants SMTP d’un fournisseur de courriel transactionnel, pour que Chatwoot puisse envoyer les réinitialisations de mot de passe et les notifications aux agents. Chatwoot est livré sans SMTP configuré par défaut.

Étape 1 : pointer le DNS vers le serveur et ouvrir le pare-feu

Créez un enregistrement A pour votre sous-domaine, pointant vers l’adresse IPv4 publique du serveur. La propagation du DNS explique pourquoi l’étape HTTPS plus loin peut échouer si vous allez trop vite, alors faites-le en premier et laissez-le se stabiliser pendant que vous avancez dans le reste de la configuration.

Sur le serveur lui-même, n’ouvrez que les ports nécessaires :

ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

Vous devriez voir Status: active avec ces trois règles listées lorsque vous exécutez ufw status.

Étape 2 : installer Docker

Le déploiement Docker de Chatwoot a besoin de Docker Engine et du plugin Compose. Le script d’installation officiel installe les deux :

curl -fsSL https://get.docker.com | sh
usermod -aG docker $(whoami)

Déconnectez-vous et reconnectez-vous pour que le changement de groupe prenne effet, puis vérifiez que les deux pièces sont présentes :

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 : générer les secrets nécessaires

Trois valeurs doivent exister avant d’écrire le fichier compose : une clé secrète Rails, un mot de passe Postgres et un mot de passe Redis. Générez les trois maintenant, pour ne pas être tenté de laisser une valeur par défaut en place :

openssl rand -hex 64   # SECRET_KEY_BASE
openssl rand -hex 24   # POSTGRES_PASSWORD
openssl rand -hex 24   # REDIS_PASSWORD

Conservez les trois résultats quelque part où vous pourrez les copier-coller. Placez-les dans un fichier .env à côté du fichier compose plutôt que de les coder en dur, afin que le fichier compose lui-même reste sécuritaire à conserver dans le contrôle de version :

mkdir -p /opt/chatwoot && cd /opt/chatwoot
cat > .env <<'EOF'
SECRET_KEY_BASE=collez-la-premiere-valeur-ici
POSTGRES_PASSWORD=collez-la-deuxieme-valeur-ici
REDIS_PASSWORD=collez-la-troisieme-valeur-ici
SMTP_ADDRESS=smtp.votre-fournisseur.com
SMTP_USERNAME=votre-nom-utilisateur-smtp
SMTP_PASSWORD=votre-mot-de-passe-smtp
EOF
chmod 600 .env

Étape 4 : écrire le fichier Compose

C’est la partie que la plupart des guides survolent : Chatwoot a besoin exactement des mêmes variables d’environnement sur le conteneur web et sur le conteneur Sidekiq, parce que Sidekiq fait tourner la même application Rails, simplement avec un processus différent. Oubliez-en une sur le worker, et les tâches en arrière-plan (envois de courriels, webhooks, sondages CSAT) échouent silencieusement même si l’interface web semble fonctionner normalement.

services:
  postgres:
    image: pgvector/pgvector:0.8.7-pg16
    restart: always
    environment:
      POSTGRES_USER: chatwoot
      POSTGRES_DB: chatwoot
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres-data:/var/lib/postgresql/data

  redis:
    image: redis:7.4.11-alpine
    restart: always
    command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"]
    volumes:
      - redis-data:/data

  rails:
    image: chatwoot/chatwoot:v4.18.0
    restart: always
    depends_on:
      - postgres
      - redis
    ports:
      - "127.0.0.1:3000:3000"
    environment:
      RAILS_ENV: production
      NODE_ENV: production
      INSTALLATION_ENV: docker
      SECRET_KEY_BASE: ${SECRET_KEY_BASE}
      FRONTEND_URL: https://chat.example.com
      REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379
      POSTGRES_HOST: postgres
      POSTGRES_USERNAME: chatwoot
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DATABASE: chatwoot
      SMTP_ADDRESS: ${SMTP_ADDRESS}
      SMTP_PORT: "587"
      SMTP_USERNAME: ${SMTP_USERNAME}
      SMTP_PASSWORD: ${SMTP_PASSWORD}
      SMTP_AUTHENTICATION: plain
      SMTP_DOMAIN: example.com
      MAILER_SENDER_EMAIL: support@example.com
    command: >
      bash -c "bundle exec rails db:chatwoot_prepare && bundle exec rails s -p 3000 -b 0.0.0.0"
    volumes:
      - storage-data:/app/storage

  sidekiq:
    image: chatwoot/chatwoot:v4.18.0
    restart: always
    depends_on:
      - postgres
      - redis
    environment:
      RAILS_ENV: production
      NODE_ENV: production
      INSTALLATION_ENV: docker
      SECRET_KEY_BASE: ${SECRET_KEY_BASE}
      FRONTEND_URL: https://chat.example.com
      REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379
      POSTGRES_HOST: postgres
      POSTGRES_USERNAME: chatwoot
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DATABASE: chatwoot
      SMTP_ADDRESS: ${SMTP_ADDRESS}
      SMTP_PORT: "587"
      SMTP_USERNAME: ${SMTP_USERNAME}
      SMTP_PASSWORD: ${SMTP_PASSWORD}
      SMTP_AUTHENTICATION: plain
      SMTP_DOMAIN: example.com
      MAILER_SENDER_EMAIL: support@example.com
    command: bundle exec sidekiq -C config/sidekiq.yml
    volumes:
      - storage-data:/app/storage

volumes:
  postgres-data:
  redis-data:
  storage-data:

Remarquez que le conteneur Rails se lie uniquement à 127.0.0.1:3000, pas à l’interface publique. Caddy, que vous allez configurer ensuite, est ce qui fait réellement face à Internet ; le conteneur de l’application ne devrait jamais être directement accessible.

Remplacez chat.example.com et support@example.com par votre vrai domaine avant de continuer. Vérifiez que le fichier s’analyse correctement :

docker compose config

Vous devriez voir la configuration résolue complète s’afficher sans erreur, et aucun ${...} restant dans la sortie.

Étape 5 : démarrer la pile

docker compose up -d

La commande du conteneur rails exécute db:chatwoot_prepare avant de démarrer le serveur web, ce qui crée la base de données, charge le schéma et insère les données initiales au premier démarrage. Observez le processus :

docker compose logs -f rails

Vous devriez voir la sortie des migrations suivie de Listening on http://0.0.0.0:3000. Confirmez ensuite que les quatre conteneurs sont bien actifs :

docker compose ps

Vous devriez voir postgres, redis, rails et sidekiq tous à l’état running ou healthy, pas restarting.

Étape 6 : installer Caddy devant, avec HTTPS automatique

Installez Caddy et donnez-lui un seul bloc de configuration. Caddy demande et renouvelle le certificat lui-même au premier démarrage, pourvu que le DNS pointe déjà vers le serveur :

apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
apt update && apt install -y caddy

Remplacez /etc/caddy/Caddyfile par :

chat.example.com {
	reverse_proxy localhost:3000
}

Puis rechargez-le :

systemctl reload caddy

Visitez https://chat.example.com dans un navigateur. Vous devriez voir un cadenas valide et l’écran de configuration de Chatwoot, pas un avertissement de certificat.

Étape 7 : sauvegarder Postgres selon un horaire

Tout ce qui compte (les conversations, les contacts, les comptes d’agents) se trouve dans le volume postgres. Un export quotidien que vous déplacez hors du serveur est le minimum acceptable comme sauvegarde :

cat > /opt/chatwoot/backup.sh <<'EOF'
#!/bin/sh
cd /opt/chatwoot
docker compose exec -T postgres pg_dump -U chatwoot chatwoot | gzip > /opt/chatwoot/backups/chatwoot-$(date +%F).sql.gz
find /opt/chatwoot/backups -mtime +14 -delete
EOF
chmod +x /opt/chatwoot/backup.sh
mkdir -p /opt/chatwoot/backups
(crontab -l 2>/dev/null; echo "0 3 * * * /opt/chatwoot/backup.sh") | crontab -

Copiez au moins un de ces fichiers .sql.gz hors du serveur (vers du stockage objet, une autre machine, n’importe où sauf ce VPS), pour qu’un disque perdu n’emporte pas vos sauvegardes avec lui. Exécutez ls /opt/chatwoot/backups le lendemain matin ; vous devriez voir un nouveau fichier daté.

Étape 8 : mettre à niveau vers une nouvelle version de Chatwoot

Chaque mise à niveau de Chatwoot nécessite de relancer la commande de migration, exactement comme au premier démarrage. Récupérez la nouvelle étiquette, exécutez la migration une fois, puis redémarrez les deux conteneurs qui utilisent l’image :

docker compose pull rails sidekiq
docker compose run --rm rails bundle exec rails db:chatwoot_prepare
docker compose up -d rails sidekiq

Vérifiez à nouveau docker compose logs -f rails. Vous devriez voir la nouvelle chaîne de version dans le journal de démarrage, et aucune erreur de migration.

Le raccourci : le faire avec Railyard

Tout ce qui précède (l’instance Postgres, l’instance Redis protégée par mot de passe, le processus web, le worker Sidekiq qui lit exactement les mêmes variables d’environnement, le volume de stockage partagé entre eux, le HTTPS sur votre domaine) est aussi disponible comme modèle dans le catalogue de modèles de Railyard. Choisissez Chatwoot là-bas, et les quatre services arrivent déjà branchés les uns aux autres : Postgres et Redis sont connectés automatiquement au processus web et au worker Sidekiq, donc aucun copier-coller de variables d’environnement entre deux conteneurs en espérant ne rien avoir oublié. Vous ajoutez tout de même votre propre fournisseur SMTP par la suite, puisque Railyard n’en configure pas un pour vous non plus. Si vous préférez partir de votre propre fourche ou d’une version modifiée de la pile, déployer depuis un dépôt et le bouton de déploiement fonctionnent de la même façon. Les sauvegardes du service Postgres sont couvertes dans bases de données et sauvegardes, et si c’est votre première fois sur Railyard, le guide de démarrage rapide couvre la configuration du compte avant tout le reste. Pour une idée du coût d’un tel serveur chez différents fournisseurs, voir coûts d’hébergement.

Dépannage

« Port is already allocated » lors de docker compose up. Autre chose sur le serveur utilise déjà le port 3000, ou vous avez lancé docker compose up deux fois sans arrêter la première exécution. Vérifiez avec ss -tlnp | grep 3000 et arrêtez ce qui occupe le port, ou changez le côté gauche de l’association de port du service rails.

La page de connexion se charge, mais les redirections ou les liens sont erronés. FRONTEND_URL doit être exactement l’URL HTTPS que les agents et les clients utiliseront, définie sur les conteneurs rails et sidekiq. Une divergence (http au lieu de https, une barre oblique finale, le mauvais sous-domaine) brise les liens de réinitialisation de mot de passe, les rappels de webhooks et même les URL des ressources du widget, même si l’application elle-même démarre sans problème.

Le certificat n’est jamais émis, les journaux de Caddy montrent des « challenge failed » répétés. C’est presque toujours une question de DNS, pas de Caddy. L’enregistrement A n’a pas encore propagé, ou ne pointe pas vers l’IP de ce serveur. Exécutez dig chat.example.com +short depuis votre propre machine et confirmez qu’il retourne bien l’IP publique réelle du serveur avant de recharger Caddy à nouveau.

Le téléversement de fichiers ou les avatars échouent avec des erreurs de permission. Le volume chatwoot-storage doit être accessible en écriture par l’utilisateur qui exécute le processus Rails dans le conteneur. Si vous avez changé le montage du volume ou migrez depuis un montage lié, vérifiez les permissions avec docker compose exec rails ls -la /app/storage plutôt que de deviner.

Le conteneur Sidekiq redémarre continuellement, ou les tâches ne se traitent jamais. Vérifiez d’abord docker compose logs sidekiq. Un worker tué par manque de mémoire (OOM) se manifeste par un redémarrage du conteneur sans erreur claire dans le journal, auquel cas la solution est plus de mémoire pour le serveur, pas un changement de configuration. S’il est actif mais que les tâches ne s’exécutent jamais, confirmez que REDIS_URL du service sidekiq correspond exactement, caractère pour caractère, à celui du service rails, mot de passe inclus.

Aucun courriel n’est jamais envoyé. Chatwoot est livré sans SMTP configuré. Si vous avez omis les variables SMTP à l’étape 4, les réinitialisations de mot de passe, les invitations d’agents et les notifications de conversation échouent toutes silencieusement. Ajoutez de vrais identifiants SMTP et redémarrez les conteneurs rails et sidekiq.

FAQ

Puis-je faire tourner Chatwoot sans Sidekiq ? Non. Les tâches en arrière-plan (envoi de courriels, webhooks, CSAT, règles d’automatisation) en dépendent ; sans lui, l’application tourne, mais de grandes parties de son fonctionnement s’arrêtent silencieusement.

Chatwoot a-t-il besoin de Redis pour autre chose que Sidekiq ? Oui, il est aussi utilisé pour la mise en cache et pour ActionCable (les mises à jour en temps réel dans le tableau de bord de l’agent), donc il est requis même si vous ne pensez pas utiliser directement de tâches en arrière-plan.

Postgres et Redis peuvent-ils tourner sur un serveur séparé, plus petit, distinct du web et du worker ? Oui, et la documentation officielle de Chatwoot mentionne cette option lorsque vous voulez utiliser des services de base de données gérés plutôt que des conteneurs. Pour une petite équipe, garder les quatre services sur une seule machine est plus simple à exploiter, et c’est ce que couvre ce guide.

Quelle est la différence entre la configuration minimale de 2 cœurs / 4 Go et celle de 4 cœurs / 8 Go ? Le chiffre le plus bas concerne le processus web seul. Le plus élevé est la recommandation officielle de Chatwoot une fois que Postgres, Redis et le worker Sidekiq se partagent le CPU et la mémoire de la même machine, ce qui est le cas normal d’une installation auto-hébergée.

Dois-je utiliser exactement les étiquettes d’image de ce guide ? Non, de nouvelles étiquettes sont publiées régulièrement. Ce guide fixe chatwoot/chatwoot:v4.18.0 parce que c’est la version réellement vérifiée de bout en bout ; consultez les notes de version du projet avant de passer à une étiquette plus récente, et relancez l’étape de migration dans tous les cas.

Une installation Chatwoot qui fonctionne, ce sont quatre petites pièces bien comprises qui se parlent correctement, pas une seule chose compliquée. Une fois le DNS, les variables d’environnement et l’étape de migration bien en place, il reste très peu à entretenir au-delà des sauvegardes et des mises à jour de version occasionnelles.

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.

Évitez la configuration du serveur

Choisissez Chatwoot dans le catalogue de modèles de Railyard pour obtenir les mêmes quatre services déjà branchés et déployés, sans toucher à un terminal.

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