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

Sim, eu faria isso em etapas:

  1. adquirir um servidor um pouco mais potente
  2. fazer a instalação dos dois contêineres funcionar

se nesse ponto você estiver satisfeito, pare por aqui, ou:

  1. implemente a página de manutenção usando o excelente guia do @Lilly acima. :+1:

Haha, estou feliz que você tenha perguntado, porque eu não tive tempo para explicar essa parte (eu deveria ter – há muito o que explicar e o Cloudflare é complexo!).

Quando a rota do worker está configurada, cada carregamento de imagem e visualização de página no fórum passa por esse worker.

O plano gratuito de CDN do Cloudflare inclui um limite de 100.000 solicitações por dia em uma rota de worker.

Portanto, se você tiver um fórum relativamente movimentado, para evitar atingir o limite do plano gratuito em um dia, é uma boa ideia não mantê-lo ativo o tempo todo. Isso se refere apenas à rota do worker, não à página de manutenção – você pode deixar a página de manutenção ativa o tempo todo; ela só será acessada se a rota do worker estiver ativa. Trata-se apenas da etapa 2 onde você atribuiu a rota (que é fácil de configurar e remover). A menos que você esteja usando um plano pago do Cloudflare, é uma boa prática mantê-lo ativo apenas quando estiver realizando sua própria manutenção.

  1. Acesse a página de rotas de workers do Cloudflare para seu domínio e clique no botão no lado direito da rota.

  1. Na parte inferior da tela de edição, clique no botão remove para desanexar a página do worker da rota.

  1. Não se preocupe, o código do worker em si não será excluído, apenas a regra de roteamento. Da próxima vez que você fizer uma reconstrução/atualização, basta adicioná-lo novamente como na Etapa 2 acima.

Se você estiver em um plano pago do Cloudflare, não há nada com que se preocupar. No entanto, nesse caso, você pode usar as páginas de erro do Cloudflare em vez de uma página de worker… (eu mencionei que o Cloudflare é bastante complexo? LOL)

:warning: configuração avançada de administrador abaixo

Se alguém quiser automatizar totalmente suas atualizações no plano gratuito, deve usar um token de API do Cloudflare, seu ID de zona e um comando curl para obter o route id (ID da rota) do worker. Em seguida, edite o script /root/update-web.sh com algumas coisas mais divertidas para ativar e desativar a rota do worker automaticamente:

#!/bin/bash
cd /var/discourse

CF_TOKEN="your_actual_token_here" #<---Token de API do Cloudflare
ZONE_ID="xxxx" #<---da sua página de perfil do Cloudflare
ROUTE_ID="xxxx"
WORKER_NAME="my-site-maintenance-page"

echo "➡️ Baixando os scripts mais recentes do Docker do Discourse..."
git pull

echo "➡️ Iniciando o container web novo em segundo plano..."
./launcher bootstrap web_only

if [ $? -eq 0 ]; then
    echo "✅ Bootstrap bem-sucedido!"
    
    # Ativar o Worker de Manutenção do Cloudflare
    echo "🚧 Habilitando a Página de Manutenção..."
    curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes/$ROUTE_ID" \
         -H "Authorization: Bearer $CF_TOKEN" \
         -H "Content-Type: application/json" \
         --data '{"pattern":"*your-site.com/*","script":"'$WORKER_NAME'"}' > /dev/null

    # Trocar os containers (Janela de indisponibilidade de 30 segundos)
    echo "🔄 Trocando containers..."
    ./launcher destroy web_only && ./launcher start web_only
    
    # Desativar o Worker de Manutenção do Cloudflare
    echo "🌍 Desabilitando a Página de Manutenção..."
    curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes/$ROUTE_ID" \
         -H "Authorization: Bearer $CF_TOKEN" \
         -H "Content-Type: application/json" \
         --data '{"pattern":"*your-site.com/*","script":null}' > /dev/null

    echo "🚀 Concluído! Site atualizado com zero indisponibilidade visível."
else
    echo "❌ Bootstrap falhou! Abortando a troca para manter o site atual online."
fi 

Eu uso a versão anterior do script porque não me importo em automatizar tudo e gosto de estar presente para fazer atualizações/reconstruções. Eu apenas adiciono a rota do worker logo antes de fazer uma atualização e a removo depois. Leva apenas alguns segundos para fazer.

Minhas etapas gerais são:

  1. Adicionar a rota do worker no Cloudflare
  2. Fazer SSH no Hetzner
  3. Fazer quaisquer atualizações do sistema (ex: sudo apt update && sudo apt upgrade -y, e reiniciar o servidor se necessário)
  4. Fazer SSH novamente se precisei reiniciar
  5. Executar ./update-web.sh
  6. Remover a rota do worker no Cloudflare

Não entendo nada de programação nem do mundo do desenvolvimento, além de ter feito uma coisa básica de hello world com Visual Basic há muito, muito tempo. Mas consigo fazer algumas coisas, porque sei administrar melhor meus servidores WordPress e Mastodon/Pixelfed, e de algum jeito também meu Discourse. Além disso, por aí existe aquela tal coisa chamada IA (que não é tão fácil para um iniciante quanto a propaganda faz parecer).

Não sei se isso é de alguma forma possível com o Discourse por causa do Docker, mas no mundo comum de Nginx-Varnish-WordPress, eu construí um sistema onde um servidor Plesk recebe informações sobre erros 50x e exibe uma página de erro. Na verdade, tenho três configurações: o Nginx da frente exibe o conteúdo de um snapshot gerado se o Varnish cair, o Varnish passa a usar o snapshot para conteúdo não em cache quando o backend relacionado ao WordPress cai, e a terceira é uma página de erro caso o Nginx da frente não responda.

As coisas do Varnish não são possíveis para o Discourse, mas não vejo nenhum motivo pelo qual não se poderia construir essa teia de segurança no mundo do Docker também, onde qualquer erro 50x exibiria uma página de erro.

Esse poderia ser um sistema muito propenso a erros, no entanto. E não faço a mínima ideia do que aconteceria se houvesse mais do que uma mão cheia de usuários.

Existe também a resposta mais óbvia, é claro: usar um Nginx antes do Discourse. Eu usei isso antes de migrar para a configuração de 2 containers.

Finalmente, tirei um tempo para reinstalar o Discourse. Depois de avaliar onde estou agora e quanta manutenção parece ser necessária para dois contêineres, acredito que vou me contentar com um por enquanto. Se eu precisar de dois contêineres no futuro, revisarei tudo o que está sendo dito aqui. Além da instalação de plugins, que não parece ser algo que eu precisarei fazer com a mesma frequência que gerenciar componentes, a comunidade ficar fora do ar por 20 minutos em um período do dia em que há menos pessoas online, junto com um banner informando às pessoas que a comunidade estará indisponível em um determinado dia e horário, parece bastante razoável por ora.

Vamos ver como vai.

Exige a mesma quantidade que um contêiner único :flushed_face:

E menos sofrimento :slight_smile:

Você pode esclarecer como isso funciona?

Não tenho certeza se você estava respondendo a mim ou ao @Jagster. O que você quis dizer?

Isso porque o processo de inicialização do novo contêiner enquanto o seu site permanece online é muito menos estressante — se a compilação falhar, você não precisa entrar em pânico e tem todo o tempo necessário para corrigir o problema sem ficar offline.

Ok, então vocês estão incentivando a ter os dois, por isso o “menos dor de cabeça”.
Então, como pessoa sem experiência quando o assunto é isso, ter 2 contêineres não significa duas instâncias do Discourse, certo?

Estou lendo o tópico

e

para ver se consigo entender quanto trabalho isso exige e a atenção que preciso ter, para não acabar com algo que não consiga gerenciar, tornando o processo mais problemático do que todas as outras coisas que podem dar errado com apenas um.

Quero apenas elogiar a partilha sobre a configuração com dois contêineres. Eu estava usando apenas um, e geralmente levava de 3 a 5 minutos (em um servidor dedicado com 64 GB de RAM).

Posso saber, com exemplos claros e simples, quando se deve atualizar ambos os contêineres em uma instalação dupla? Quero dizer, quais atualizações do Discourse devem reiniciar ambos e quais apenas o recém-criado web_container?

Primeiro, você segue instruções muito simples sobre como iniciar o 2-container. Depois disso, na maioria das vezes, você só precisa de

./launcher bootstrap web_only && ./launcher destroy web_only && ./launcher start web_only ) 2>&1 | tee ~/$(date +%Y-%m-%d_%H-%M-%S)-upgrade.log'

A parte do tee é apenas para registro em log, porque é mais fácil (para mim) navegar por ele do que pelo feed do tmux que estou usando.

Mas, basicamente, é exatamente o mesmo que usar app.yml e reconstruir, exceto que incomoda muito menos os usuários. Claro, existe o data-container, mas ele precisa de amor e cuidado muito raramente — e se você for fazer truques mais sofisticados com o container, provavelmente sabe o que fazer e quando fazer com os containers também.

Se a atualização falhar no 2-container, você ainda terá um fórum no ar e funcionando, enquanto um único container pode travar.

Então, apenas o início é um pouco mais exigente, mas as instruções são bastante claras. Eu diria que usar o mail-reveiver é uma tarefa mais difícil, se estiver usando o Amazon SES.

Por exemplo, esse é o tipo de comentário que não posso simplesmente ignorar, pois parece que atualizar/fazer upgrade deixa de ser tão simples quanto clicar em um botão, passando a exigir mais atenção e cuidado. Para uma pessoa experiente, isso pode parecer fácil e óbvio, mas talvez não seja o caso para quem não é:

Você diria que as instruções neste tópico ainda são válidas em 2026, considerando que ele é de 2015?

Não me importo em tentar, já que acabei de instalar o Discourse de novo hoje. Se algo der errado, posso simplesmente voltar para um único contêiner. Só quero ter certeza de que, no meio do processo, não vou fazer algo que já não seja mais válido em 2026…

Para mim, a economia de alguns minutos é de mais de 20 minutos. A afirmação de que é uma vez por mês é verdadeira se a atualização for feita uma vez por mês, mas eu faço atualizações pelo menos duas vezes por semana. E se algum plugin falhar e for necessário fazer várias tentativas (porque, claro, estamos trabalhando com instâncias ativas :wink:), esse longo tempo de inatividade é apenas uma dor de cabeça.

Não há detalhes nos anúncios de cada nova versão para serem seguidos. Mcdanlj pode ter, mas ele não é um sysadmin comum, pois trabalha em um nível muito mais alto.

Estou confuso…

Enquanto você diz:

sua resposta acima desta dá a entender que há mais trabalho, quando você diz:

Isso, por si só, dá a impressão de que dois containers são realmente mais complexos de manter, e não o mesmo que um? Claro, entendo a questão do tempo de inatividade e tudo mais, mas a manutenção dos próprios containers parece mais complexa e mais propensa a erros do que uma simples atualização com um único container. Ou estou perdendo algo?

isso está correto:

Contêiner 1 = site & nginx
Contêiner 2 = banco de dados e redis

(acho que estou certo nisso)

As coisas do Contêiner 1 mudam muito

As coisas do Contêiner 2 raramente mudam.

E você pode atualizar o Contêiner 1 sem atualizar o Contêiner 2.

E, melhor ainda, você pode preparar um substituto para o Contêiner 1 e depois trocá-lo em poucos segundos (a preparação é chamada de “bootstrapping”)

Você está esquecendo que, com um único container, o comando ./launcher rebuild app interrompe tanto a parte web quanto a de dados, ambos são atualizados, mas a parte de dados raramente precisa disso, e após a tarefa tudo é reiniciado se não houver nenhum problema.

Com dois containers, você reconstrói apenas o “web”, sem o container de dados; então, se tudo correr bem, ele destruirá o container antigo e iniciará o novo. Se algo der errado, seu “web” antigo e funcional continuará em uso.

Portanto, a única diferença real é como lidar com o software e algumas outras coisas do banco de dados.

Claro, a configuração com um único contêiner também é uma opção, é claro. Mas o ponto principal é que, quando se usa dois contêineres, a única diferença real no nome da dificuldade é o comando usado na atualização — e para isso existe o alias :wink:

Isso foi escrito nos velhos tempos dos anúncios escritos à mão, que diziam algo sobre ser hora de atualizar o banco de dados agora. O novo site automatizado é mais chamativo, mas não há mais uma nota humana sobre o que realmente é mais importante, como costumava haver.

Hoje, imagino que você precise notar um post informando que o banco de dados está sendo atualizado? Acho que perdi esses avisos por meses.

No entanto, isso acontece a cada poucos anos, e o banco é reconstruído quando você explicitamente reconstrói o banco de dados, e o CDCK parece ter mantido a compatibilidade com versões mais antigas do pgsql por um tempo. Então, nunca realmente me causou problemas. Até agora.

Eu realmente gosto da configuração de dois contêineres (ou mais!) para mim mesmo, mas ainda faço uma ressalva, porque não é a mais fácil para todos. É difícil para mim julgar para quem a implantação com dois contêineres parecerá “claro, isso é simples” e para quem será “ai, eu só quero apertar um botão”.