Corrige acesso em produção: hosts permitidos, i18n do Devise e config do ambiente no compose

- production.rb (hosts): a linha que parecia só liberar o APP_HOST na verdade
  LIGAVA a verificação de Host e recusava todo o resto — o acesso pelo IP
  interno caía em 'Blocked hosts: 100.75.222.23:3001'. Agora entram também
  localhost/127.0.0.1 e a lista HOSTS_PERMITIDOS.
- production.rb (i18n): 'fallbacks = true' significa cair no default_locale,
  que aqui é o próprio pt-BR — o fallback apontava para si mesmo e chave
  ausente virava 'Translation missing' na tela do usuário. Agora [:en], igual
  ao application.rb.
- pt-BR.yml: traduções do Devise (failure/sessions/passwords). O projeto não
  usa devise-i18n; em development o texto vinha em inglês pelo fallback e o
  buraco passava despercebido.
- docker-compose.yml / .env.example: porta do host parametrizada
  (${PORTA_APP:-3001}) e APP_HOST/APP_NAME/WHATSAPP_URL/HOSTS_PERMITIDOS com
  padrão — essa configuração vivia só no .env do servidor e sumiu junto com ele.
This commit is contained in:
2026-08-27 18:30:17 -03:00
parent a06f93784c
commit 7fa2336b35
4 changed files with 115 additions and 11 deletions

View File

@@ -21,11 +21,42 @@ Rails.application.configure do
config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = { host: ENV.fetch("APP_HOST", "localhost:3000") }
config.i18n.fallbacks = true
# `= true` significa "caia no default_locale" — e o default AQUI é o próprio
# pt-BR, então o fallback apontava para si mesmo e qualquer chave ausente
# virava "Translation missing" NA TELA DO USUÁRIO (aconteceu em 27/08/2026 na
# tela de login, com devise.failure.unauthenticated). Em development o
# config/application.rb já usa [:en] e por isso o problema não aparecia lá.
# Mantido igual ao application.rb: chave faltando mostra o texto em inglês,
# que é feio mas legível — nunca a mensagem de erro do i18n.
config.i18n.fallbacks = [:en]
config.active_support.report_deprecations = false
config.active_record.dump_schema_after_migration = false
# Aceita o host configurado no .env
# ── Hosts aceitos (proteção contra DNS rebinding) ─────────────────────────
# Regra do Rails: lista VAZIA = aceita qualquer Host; lista com QUALQUER item
# = só o que estiver nela entra. Por isso a linha abaixo, que parece só
# "liberar o APP_HOST", na verdade LIGA a verificação e bloqueia todo o resto
# com "ActionDispatch::HostAuthorization ... Blocked hosts: <host>".
#
# ⚠️ APP_HOST tem que vir SEM "https://": com o esquema, este split libera um
# host chamado "https" e nada funciona.
config.hosts << ENV["APP_HOST"]&.split(":")&.first if ENV["APP_HOST"].present?
# O próprio servidor. Sem isto, um `curl http://127.0.0.1:3001/` de dentro do
# NAS — que é o teste que separa "app caiu" de "proxy errado" — volta
# bloqueado e faz parecer que a aplicação está quebrada.
config.hosts += ["localhost", "127.0.0.1", "[::1]"]
# Endereços extras, separados por vírgula. Caso real (27/08/2026): o acesso
# pela rede interna chega com `Host: 100.75.222.23:3001` (o IP do NAS), que
# não bate com o domínio público e caía em "Blocked hosts". A porta é
# ignorada pelo Rails na comparação — basta o IP/nome.
# HOSTS_PERMITIDOS=100.75.222.23,10.0.0.20
ENV.fetch("HOSTS_PERMITIDOS", "").split(",").map(&:strip).reject(&:empty?).each do |permitido|
config.hosts << permitido
end
# Escotilha de emergência: desliga a verificação por completo. Último recurso —
# com ela ligada, qualquer domínio apontado para este servidor é aceito.
config.hosts.clear if ENV["RAILS_ALLOW_ALL_HOSTS"] == "true"
end