Bonjour l’équipe,
je signale un mode de défaillance dans la configuration officielle Docker/runit qui peut tuer silencieusement Sidekiq (et donc les tâches d’IA/de fond) sans aucune reconstruction ni mise à jour.
Environnement
- Installation officielle de Discourse Docker (conteneur standard + services runit).
- Aucune reconstruction/mise à jour juste avant le début du problème.
- Plugin Discourse AI activé, mais l’IA a cessé de répondre.
Symptômes
- L’IA semble activée dans l’interface d’administration, mais aucune réponse de l’IA n’apparaît.
- Les tâches de fond (IA/embeddings/réponse automatique) semblent bloquées.
sv status sidekiqmontre que Sidekiq meurt de manière répétée juste après le démarrage :
down: sidekiq: 1s, normally up, want up
- Le démarrage manuel de Sidekiq fonctionne bien, donc l’application elle-même est OK :
bundle exec sidekiq -C config/sidekiq.yml
# reste actif, se connecte à Redis, traite les tâches
Ce que nous avons trouvé
Le script runit par défaut était :
exec chpst -u discourse:www-data \
bash -lc 'cd /var/www/discourse && ... bundle exec sidekiq -e production -L log/sidekiq.log'
Deux points de fragilité :
- Groupe principal www-data Dans mon conteneur, les chemins inscriptibles typiques appartiennent à discourse:discourse. Tout décalage dans tmp/pids ou les chemins partagés peut faire que Sidekiq se termine au démarrage lorsqu’il est exécuté sous www-data, même si le démarrage manuel en tant que discourse fonctionne.
- Écriture forcée -L log/sidekiq.log dans les journaux partagés Le chemin du journal est un lien symbolique vers
/shared/log/rails/sidekiq.log. Si ce fichier/répertoire est recréé avec des propriétaires/permissions différents, Sidekiq peut se terminer immédiatement avant de produire des journaux utiles.
Déclencheur connexe : logrotate échoue quotidiennement
Séparément, logrotate échouait tous les jours avec :
error: skipping "..."log" because parent directory has insecure permissions
Set "su" directive in config file ...
La cause était les permissions Debian/Ubuntu standard :
/var/logest root:adm avec 0775 (groupe inscriptible).- logrotate refuse la rotation à moins qu’une directive
suglobale ne soit définie. C’est le comportement attendu en amont.
Au moment où la tâche quotidienne de logrotate a échoué, elle a également recréé des fichiers sous /shared/log/rails/ (y compris sidekiq.log), ce qui a probablement interagi avec la journalisation forcée via -L et a contribué à la boucle de crash de Sidekiq « 1s ».
Correction (aucune reconstruction nécessaire)
- Corriger logrotate pour qu’il arrête de toucher aux journaux partagés dans un état d’échec Ajouter une directive
suglobale :
# /etc/logrotate.conf (en haut)
su root adm
Après cela, logrotate -v sort avec 0 et ne signale plus de permissions de répertoire parent non sécurisées.
- Remplacer le script runit de Sidekiq par un défaut plus robuste Passer à
discourse:discourseet ausidekiq.ymlstandard, et ne pas forcer-L log/sidekiq.log, rend Sidekiq stable :
#!/bin/bash
exec 2>&1
cd /var/www/discourse
mkdir -p tmp/pids
chown discourse:discourse tmp/pids || true
exec chpst -u discourse:discourse \
bash -lc 'cd /var/www/discourse && rm -f tmp/pids/sidekiq*.pid; exec bundle exec sidekiq -C config/sidekiq.yml'
Après cela :
sv status sidekiqresterun:- Les tâches IA/de fond reprennent.
Demande / suggestion
Pourrions-nous envisager de rendre le service Sidekiq officiel Docker/runit plus robuste par défaut ?
Par exemple :
- Exécuter Sidekiq sous
discourse:discourse(correspondant à la propriété typique à l’intérieur du conteneur). - Préférer
bundle exec sidekiq -C config/sidekiq.yml. - Éviter de forcer un fichier journal partagé via
-L log/sidekiq.log, ou le rendre résilient à la dérive des permissions du volume partagé/logrotate.
Même une note de documentation (« si Sidekiq affiche down: 1s mais que le démarrage manuel fonctionne, vérifiez /etc/service/sidekiq/run et évitez la journalisation forcée partagée ») aiderait grandement les auto-hébergeurs.
Heureux de fournir plus de journaux si nécessaire. Merci !