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 sidekiqmostra 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à:
- 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.
- 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
suglobale. 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)
- Correggere logrotate in modo che smetta di toccare i log condivisi in stato di errore Aggiungere una direttiva
suglobale:
# /etc/logrotate.conf (inizio)
su root adm
Dopodiché, logrotate -v esce con 0 e non segnala più permessi non sicuri della directory padre.
- Sostituire lo script runit di Sidekiq con uno predefinito più robusto Passare a
discourse:discoursee alsidekiq.ymlstandard, 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 sidekiqrimane 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!