Solução alternativa para página de manutenção - isso é possível?

Eu uso a construção de contêiner duplo por trás do CDN do Cloudflare. O contêiner duplo minimiza o tempo de inatividade e meus dois fóruns de produção principais têm no máximo 30 segundos offline durante as reconstruções. Eu gosto de ter uma página de manutenção porque a página padrão de servidor web está inativa é feia e não dá nenhuma dica sobre por quanto tempo ela estará offline.

por exemplo, para um site em your-domain.com eu simplesmente uso uma rota de trabalhador do Cloudflare definida como `yourdomain.com/.

Etapa 1: Crie a página do trabalhador

você pode configurar a página de manutenção na página de configurações workers & pages no Cloudflare - clique no botão create application:

então use o modelo hello world:

então dê a ele um nome e clique em deploy:

então vá para a página de visão geral dessa página de manutenção e clique em edit code:

e cole este código na janela de código worker.js (substitua seu domínio e qualquer mensagem que você queira, edite o texto, a cor do texto, o fundo, etc):

export default {
  async fetch(request, env, ctx) {
    try {
      // Busca a solicitação original do seu servidor
      const response = await fetch(request);

      // Se SEU SITE estiver trocando contêineres, ele gera um erro 502, 521 ou 530
      if (response.status === 502 || response.status === 521 || response.status === 530) {
        return returnCustomErrorPage();
      }

      // Se tudo estiver bem, retorne o tráfego normal do fórum
      return response;
    } catch (e) {
      // Se o servidor estiver completamente inacessível
      return returnCustomErrorPage();
    }
  }
};

function returnCustomErrorPage() {
  const html = `
    <!DOCTYPE html>
    <html lang="pt-BR">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Atualização do Sistema - YOUR-SITE.com</title>
      <style>
        body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; text-align: center; padding: 50px; color: #333; background-color: #f9f9f9; }
        h1 { font-size: 2.5em; margin-bottom: 0.5em; color: #9400D3; }
        p { font-size: 1.2em; line-height: 1.5; }
        .container { max-width: 600px; margin: 0 auto; background: white; padding: 40px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
      </style>
    </head>
    <body>
      <div class="container">
        <h1>Apenas uma breve janela de atualização</h1>
        <p><strong>YOUR-SITE</strong> está passando por uma breve atualização de sistema de 30 segundos.</p>
        <p>Tomem um gole rápido da sua bebida — esta página será atualizada automaticamente assim que estivermos de volta online.</p>
      </div>
      <script>
        // Verifica automaticamente se o site está de volta a cada 10 segundos
        setInterval(function() {
          window.location.reload();
        }, 10000);
      </script>
    </body>
    </html>
  `;

  return new Response(html, {
    status: 503, // 503 é o melhor para SEO, para que o Google não penalize você por tempo de inatividade
    headers: {
      "Content-Type": "text/html;charset=UTF-8",
      "Retry-After": "30"
    }
  });
}

deve ficar mais ou menos assim. clique em deploy para salvá-lo:

Etapa 2: Adicione a rota

agora vá para a página de rotas do trabalhador do Cloudflare e clique no botão add route para abrir o modal de nova rota, preencha a rota do domínio e selecione a página do trabalhador que você acabou de criar, então clique em salvar:

Etapa 3: Executando atualizações ou reconstruções

agora, quando você ssh para seu servidor e executar suas atualizações do sistema ou fazer uma reconstrução, em vez de uma página de site inativo ou erro, esta página será exibida quando o tempo de inatividade realmente acontecer (eu uso 30 segundos no meu porque esse é o máximo para meus sites)

eu tendem a adicionar e excluir minha página de rota de trabalhadores sempre que estou fazendo manutenção, mas alguns gostam de simplesmente deixá-lo lá o tempo todo (eu deixo o código real para a página, eu apenas adiciono e removo a rota).

eu acho que é isso.

Opcional: Execute atualizações com um script e agende

eu também uso um script de shell unix em meu servidor para executar a atualização específica do contêiner duplo, que eu criei assim:

cat << 'EOF' > /root/update-web.sh
#!/bin/bash
cd /var/discourse
echo "➡️ Baixando os scripts mais recentes do Docker Discourse..."
git pull

echo "➡️ Bootstrapando novo contêiner web em segundo plano (leva ~8 minutos)..."
./launcher bootstrap web_only

if [ $? -eq 0 ]; then
    echo "✅ Bootstrap bem-sucedido! Trocando contêineres..."
    ./launcher destroy web_only && ./launcher start web_only
    echo "🚀 Pronto! Site atualizado com quase zero tempo de inatividade."
else
    echo "❌ Bootstrap falhou! Abortando troca para manter o site atual online."
fi
EOF

chmod +x /root/update-web.sh

então eu o executo no prompt root em meu servidor com o comando ./update-web.sh.

você pode automatizá-lo para um horário específico, como 1 da manhã de domingo no seu horário local com um trabalho cron. para mim 1:00am local é 8:00 AM UTC, (você pode descobrir a data UTC do seu servidor) digitando date no prompt de comando quando estiver ssh’d.

então:

execute este comando para abrir o agendador de tarefas do seu servidor:

crontab -e

(se ele pedir para você escolher um editor, pressione seu editor preferido, 1 para nano é provavelmente o mais fácil)

eu rolo para o final dos comentários e cole isto:

0 8 * * 0 /root/update-web.sh >> /var/log/discourse-update.log 2>&1

(o que significa executar o arquivo /root/update-web.sh no minuto 0, hora 8 (UTC), toda manhã de domingo)

então salve e saia (se você estiver usando nano):

  1. Ctrl + O para salvar.
  2. Enter para confirmar.
  3. Ctrl + X para sair.

então eu posso executar cat /var/log/discourse-update.log quando eu acordar nas manhãs de domingo para verificar se ele foi executado corretamente. se você usar um agendador de tarefas cron, então você querer deixar a rota da página de trabalhadores.

eu acho que é tudo. me avise se você tiver perguntas lol. é muito mais simples do que eu fiz parecer lol. :grin: