Olá equipe,
relatando um modo de falha na configuração oficial do Docker/runit que pode encerrar silenciosamente o Sidekiq (e, portanto, os trabalhos de IA/background) sem qualquer reconstrução ou atualização.
Ambiente
- Instalação oficial do Discourse Docker (container padrão + serviços runit).
- Nenhuma reconstrução/atualização imediatamente antes do início do problema.
- Plugin Discourse AI ativado, mas a IA parou de responder.
Sintomas
- A IA parece ativada na interface de administração, mas nenhuma resposta de IA aparece.
- Os trabalhos em segundo plano (IA/embeddings/resposta automática) parecem travados.
sv status sidekiqmostra o Sidekiq morrendo repetidamente logo após a inicialização:
down: sidekiq: 1s, normally up, want up
- Iniciar o Sidekiq manualmente funciona bem, então o aplicativo em si está OK:
bundle exec sidekiq -C config/sidekiq.yml
# permanece ativo, conecta-se ao Redis, processa trabalhos
O que descobrimos
O script runit padrão era:
exec chpst -u discourse:www-data \
bash -lc 'cd /var/www/discourse && ... bundle exec sidekiq -e production -L log/sidekiq.log'
Dois pontos de fragilidade:
- Grupo primário www-data No meu container, os caminhos graváveis típicos são de propriedade de discourse:discourse. Qualquer desvio em tmp/pids ou caminhos compartilhados pode fazer com que o Sidekiq saia durante a inicialização quando executado sob www-data, mesmo que a inicialização manual como discourse funcione.
- Escrita forçada -L log/sidekiq.log para logs compartilhados O caminho do log é um link simbólico para
/shared/log/rails/sidekiq.log. Se esse arquivo/diretório for recriado com propriedade/permissões diferentes, o Sidekiq pode sair imediatamente antes de produzir logs úteis.
Gatilho relacionado: logrotate falhando diariamente
Separadamente, o logrotate estava falhando todos os dias com:
error: skipping "...log" because parent directory has insecure permissions
Set "su" directive in config file ...
A causa eram as permissões padrão do Debian/Ubuntu:
/var/logé root:adm com 0775 (grupo gravável).- logrotate se recusa a rotacionar, a menos que uma diretiva
suglobal seja definida. Este é o comportamento upstream esperado.
No momento em que o trabalho diário do logrotate falhou, ele também recriou arquivos em /shared/log/rails/ (incluindo sidekiq.log), o que provavelmente interagiu com o log forçado via -L e contribuiu para o loop de “crash de 1s” do Sidekiq.
Correção (nenhuma reconstrução necessária)
- Corrigir logrotate para que ele pare de tocar nos logs compartilhados em estado de falha Adicionar uma diretiva
suglobal:
# /etc/logrotate.conf (topo)
su root adm
Depois disso, logrotate -v sai com código 0 e não relata mais permissões de diretório pai inseguras.
- Substituir o script runit do Sidekiq por um padrão mais robusto Mudar para
discourse:discoursee osidekiq.ymlpadrão, e não forçar-L log/sidekiq.log, torna o Sidekiq estável:
#!/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'
Depois disso:
sv status sidekiqpermanece em execução:- Os trabalhos de IA/background são retomados.
Solicitação / sugestão
Poderíamos considerar tornar o serviço Sidekiq oficial do Docker/runit mais robusto por padrão?
Por exemplo:
- Executar o Sidekiq sob
discourse:discourse(correspondendo à propriedade típica dentro do container). - Preferir
bundle exec sidekiq -C config/sidekiq.yml. - Evitar forçar um arquivo de log compartilhado via
-L log/sidekiq.log, ou torná-lo resiliente à deriva de permissões do volume compartilhado/logrotate.
Mesmo uma nota na documentação (“se o Sidekiq mostrar down: 1s, mas a inicialização manual funcionar, verifique /etc/service/sidekiq/run e evite o log forçado compartilhado”) ajudaria muito os auto-hospedeiros.
Fico feliz em fornecer mais logs, se necessário. Obrigado!