Script runit di Sidekiq troppo fragile: **discourse:www-data** **+ forced** **-L log/sidekiq.log** **causa crash di 1 secondo**

Ciao team,

segnalo una modalità di fallimento nella configurazione ufficiale Docker/runit che può terminare silenziosamente Sidekiq (e quindi i job AI/in background) senza alcuna ricostruzione o aggiornamento.

Ambiente

  • Installazione ufficiale di Discourse Docker (container standard + servizi runit).
  • Nessuna ricostruzione/aggiornamento immediatamente prima dell’inizio del problema.
  • Plugin Discourse AI abilitato, ma l’AI ha smesso di rispondere.

Sintomi

  • L’AI risulta abilitata nell’interfaccia di amministrazione, ma non compaiono risposte dall’AI.
  • I job in background (AI/embedding/risposta automatica) sembrano bloccati.
  • sv status sidekiq mostra che Sidekiq muore ripetutamente subito dopo l’avvio:
down: sidekiq: 1s, normally up, want up
  • L’avvio manuale di Sidekiq funziona correttamente, quindi l’applicazione è a posto:
bundle exec sidekiq -C config/sidekiq.yml
# rimane attivo, si connette a Redis, elabora i job

Cosa abbiamo scoperto

Lo script runit predefinito era:

exec chpst -u discourse:www-data \
  bash -lc 'cd /var/www/discourse && ... bundle exec sidekiq -e production -L log/sidekiq.log'

Due punti di fragilità:

  1. Gruppo primario www-data Nel mio container, i percorsi tipicamente scrivibili sono di proprietà di discourse:discourse. Qualsiasi deriva in tmp/pids o nei percorsi condivisi può far uscire Sidekiq durante l’avvio quando eseguito sotto www-data, anche se l’avvio manuale come discourse funziona.
  2. Scrittura forzata -L log/sidekiq.log nei log condivisi Il percorso del log è un collegamento simbolico a /shared/log/rails/sidekiq.log. Se quel file/directory viene ricreato con proprietà/permessi diversi, Sidekiq può uscire immediatamente prima di produrre log utili.

Trigger correlato: logrotate fallisce quotidianamente

Separately, logrotate falliva ogni giorno con:

error: skipping "...\log" because parent directory has insecure permissions
Set "su" directive in config file ...

La causa erano i permessi standard Debian/Ubuntu:

  • /var/log è root:adm con 0775 (scrivibile dal gruppo).
  • logrotate rifiuta la rotazione a meno che non venga impostata una direttiva su globale. Questo è il comportamento previsto a monte.

Nel momento in cui il job giornaliero di logrotate è fallito, ha anche ricreato i file sotto /shared/log/rails/ (incluso sidekiq.log), che probabilmente ha interagito con la registrazione forzata tramite -L e ha contribuito al ciclo di crash di Sidekiq “1s”.

Correzione (nessuna ricostruzione necessaria)

  1. Correggere logrotate in modo che smetta di toccare i log condivisi in stato di errore Aggiungere una direttiva su globale:
# /etc/logrotate.conf (inizio)
su root adm

Dopodiché, logrotate -v esce con 0 e non segnala più permessi non sicuri della directory padre.

  1. Sostituire lo script runit di Sidekiq con uno predefinito più robusto Passare a discourse:discourse e al sidekiq.yml standard, e non forzare -L log/sidekiq.log, rende Sidekiq stabile:
#!/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'

Dopo questo:

  • sv status sidekiq rimane in esecuzione:
  • I job AI/in background riprendono.

Richiesta / suggerimento

Potremmo considerare di rendere il servizio Sidekiq ufficiale Docker/runit più robusto per impostazione predefinita?

Ad esempio:

  • Eseguire Sidekiq sotto discourse:discourse (corrispondente alla proprietà tipica all’interno del container).
  • Preferire bundle exec sidekiq -C config/sidekiq.yml.
  • Evitare di forzare un file di log condiviso tramite -L log/sidekiq.log, o renderlo resiliente alla deriva dei permessi di logrotate/volume condiviso.

Anche una nota nella documentazione (“se Sidekiq mostra down: 1s ma l’avvio manuale funziona, controllare /etc/service/sidekiq/run ed evitare la registrazione condivisa forzata”) aiuterebbe molto gli self-hoster.

Sono disponibile a fornire ulteriori log se necessario. Grazie!