Aviso: Se você não se sente confortável atuando como administrador de sistemas Linux e não tem experiência com contêineres Docker, migrar para uma implantação com múltiplos contêineres causará dificuldades. Nesse caso, tanto a equipe quanto os voluntários aqui pedirão apropriadamente que você retorne a uma implantação única e independente, totalmente gerenciada pelo script
launcher.Se você migrar para uma implantação com múltiplos contêineres e seu sistema quebrar como resultado, é provável que você tenha a oportunidade de manter ambas as partes quebradas. Se você ler as instruções abaixo e parecer mágica, em vez de esclarecer como as coisas realmente funcionam dentro dos contêineres, corra, não caminhe, até sua implantação independente padrão mais próxima; isso fará um favor a você.
O método recomendado para migrar de uma implantação de contêiner único para uma implantação com múltiplos contêineres é essencialmente:
- Faça um backup do seu Discourse
- Jogue tudo fora
- Comece do zero com uma implantação com múltiplos contêineres
- Restaure seu backup
Se, como eu, você tiver um site grande que leva horas para restaurar, talvez se pergunte se existe uma maneira mais rápida. Não se pergunte mais! Eu migrei de uma implantação independente para uma implantação com três contêineres (web, dados e Redis) em menos tempo do que normalmente leva para ./launcher rebuild app nesse site. (12 minutos de tempo total de inatividade, enquanto reconstruir o aplicativo às vezes leva mais de 30 minutos.) Com base na minha experiência, eu manteria o Redis junto com o Postgres em um único contêiner de dados no futuro.
Se você fizer isso, assume a responsabilidade de saber quando precisa reconstruir seus outros contêineres (dados e, se for tolo como eu e separar o Redis, o Redis também). Você não receberá mais atualizações gratuitas de tudo com ./launcher rebuild app — se não tiver recursos para gerenciar esse processo, use uma implantação independente ou adquira o Discourse hospedado.
Teste
Não use este processo para migrar para múltiplos contêineres a menos que, após lê-lo, você também entenda como ele indicaria como migrar rapidamente de múltiplos contêineres para um único contêiner. Se isso não for óbvio para você após a leitura, então este post é uma tecnologia suficientemente avançada (ou seja, indistinguível de mágica), e é possível que você também não reconheça se esse processo quebrar no meio do caminho. Nesse caso, você pode acabar com um Discourse quebrado que só reconhecerá muito mais tarde. Se isso acontecer, você terá que manter ambas as partes quebradas. Quebrou, comprou, como dizem!
Backup
Faça o backup primeiro e ative os backups de miniaturas primeiro, para que você não precise reconstruí-los todos na restauração. Se você cometer um erro aqui, facilmente entrará em uma situação em que a maneira mais fácil, segura e rápida de recuperar é mudar para o método normal. Esteja pronto para voltar ao método recomendado se algo der errado.
Baixe seu backup. Os comandos abaixo envolvem mover arquivos dentro dos dados do Discourse e, se você cometer um erro, talvez tenha excluído seu backup. Então, baixe-o. E, se seu backup não incluir uploads, faça backup deles também. Eles também estão localizados onde você estará movendo arquivos.
Sério, faça o backup.
Quando fiz isso, primeiro fiz um backup, depois fiz um backup remoto do sistema, antes de prosseguir.
Configurar nova configuração com múltiplos contêineres
Você precisará de pelo menos containers/web_only.yml e containers/data.yml e, se também quiser separar o Redis, também de containers/redis.yml. Comece copiando samples/data.yml (e opcionalmente samples/redis.yml) para o diretório containers/.
Se estiver implantando o Redis separadamente, remova o modelo do Redis do topo do arquivo containers/data.yml. (Mas não faça isso sem um bom motivo; é apenas trabalho extra.)
Você tem duas maneiras de criar o web_only.yml.
- Copie
samples/web_only.ymlparacontainers/; depois, compare ambos comcontainers/app.yml, preservando qualquer configuração do Postgres emparams:no seu novocontainers/data.yml
- Copie qualquer
params:para o Postgres decontainers/app.ymlparacontainers/data.yml - Crie uma senha única para substituir
SOME_SECRET
- Alternativamente, copie
containers/app.ymlparacontainers/web_only.ymle compare-o comsamples/web_only.yml,
- Remova todas as referências aos modelos do Postgres e Redis
- Remova a seção inteira
params:que continha apenas configurações do Postgres - Adicione uma seção
links:, literalmente desamples/web_only.ymlou modificada (veja abaixo) se estiver implantando o Redis em um contêiner separado - Adicione uma seção de banco de dados de
samples/web_only.ymle crie uma senha única para substituirSOME_SECRET - Altere as definições de volume de
standaloneparaweb_only
Aqui está a seção links: para usar se estiver separando o Redis em seu próprio contêiner, em vez de usar a configuração razoável padrão de agrupá-lo com o Postgres no contêiner de dados:
# Use a chave 'links' para vincular contêineres, ou seja, use a flag Docker --link.
links:
- link:
name: data
alias: data
- link:
name: redis
alias: redis
O link redis não é necessário se estiver combinando os contêineres Redis e Postgres como um único contêiner de dados; isso serve apenas para mostrar o que você faria.
Aqui está uma cópia das configurações atuais do Postgres em env em samples/data.yml nas quais você precisará alterar SOME_SECRET:
## TODO: configurar conectividade com os bancos de dados
DISCOURSE_DB_SOCKET: ''
#DISCOURSE_DB_USERNAME: discourse
DISCOURSE_DB_PASSWORD: SOME_SECRET
DISCOURSE_DB_HOST: data
## Se usar um único contêiner de dados+redis, o seguinte será "data"
DISCOURSE_REDIS_HOST: redis
Note que, para uma implantação normal (não multisite), você não precisará modificar nenhuma outra linha. DISCOURSE_DB_SOCKET é para um socket de domínio Unix para o Postgres; não é um número de porta.
Aqui está um exemplo da alteração na definição de volumes no final do web_only.yml que você precisará usar se o copiar de app.yml em vez de samples/web_only.yml:
@@ -75,10 +80,10 @@
## O contêiner Docker é sem estado; todos os dados são armazenados em /shared
volumes:
- volume:
- host: /var/discourse/shared/standalone
+ host: /var/discourse/shared/web_only
guest: /shared
- volume:
- host: /var/discourse/shared/standalone/log/var-log
+ host: /var/discourse/shared/web_only/log/var-log
guest: /var/log
Agora, defina a mesma senha secreta usada em containers/web_only.yml em containers/data.yml no lugar de SOME_SECRET.
Agora você está pronto para a migração.
Agora é o momento de fazer e baixar seu backup final antes de tentar a migração rápida. Lembre-se: se algo der errado aqui, vá imediatamente para o método recomendado. Não posso enfatizar isso o suficiente.
Contêineres de dados (Postgres) e Redis separados:
cd /var/discourse
./launcher stop app
cd shared
mkdir data
mkdir redis
mv standalone/postgres_* data/
mv standalone/redis_data/ redis/
mv standalone web_only
mkdir -p data/log/var-log
mkdir -p redis/log/var-log
cd ..
./launcher destroy app
./launcher bootstrap data
./launcher bootstrap redis
./launcher start redis
./launcher start data
./launcher bootstrap web_only
./launcher start web_only
Contêiner de dados combinado Postgres+Redis:
cd /var/discourse
./launcher stop app
cd shared
mkdir data
mv standalone/postgres_* data/
mv standalone/redis_data/ data/
mv standalone web_only
mkdir -p data/log/var-log
cd ..
./launcher destroy app
./launcher bootstrap data
./launcher start data
./launcher bootstrap web_only
./launcher start web_only
Note também que, se você configurou anteriormente um nginx externo, precisará alterar o caminho proxy_pass para corresponder ao novo local do socket web_only; por exemplo, de http://unix:/var/discourse/shared/standalone/nginx.http.sock: para http://unix:/var/discourse/shared/web_only/nginx.http.sock:
Para mim, em uma VM de 2 núcleos com 4 GB de RAM e um site com backups de 600 MB sem downloads, esse processo resultou em 12 minutos de inatividade. Sua experiência pode variar.
Note que nada disso até agora atualiza o launcher. Você pode não estar atualizado. (Por exemplo, executei isso após a atualização do Postgres 12 estar disponível, mas antes de aplicá-la. Esse processo deixou-me com o Postgres 10. Em seguida, a próxima coisa que fiz foi reconstruir o aplicativo de dados, o que atualizou o launcher e me levou com sucesso pelo processo de atualização do Postgres 12.)
O que fazer em atualizações futuras
Após essa migração, se precisar atualizar o Redis ou os dados, primeiro deve parar o aplicativo web. Isso se pareceria mais ou menos com isso:
./launcher stop web_only
./launcher rebuild data # e/ou redis
./launcher rebuild web_only
Note que, se você reconstruir o contêiner data (ou postgres, ou redis) precisará criar um novo contêiner web para reconectá-lo ao novo contêiner de dados. Você pode fazer isso reconstruindo web_only ou, se achar que não precisa reconstruí-lo, um ./launcher destroy web_only; ./launcher start web_only fará o trabalho (e se receber um erro sobre “contêiner de dados ausente” ou similar, é isso que você precisa fazer).
No entanto, quando nem o Postgres nem o Redis precisam de atualização, é muito mais rápido não ter que reconstruir esses contêineres, e a maioria das reconstruções de aplicativo é apenas ./launcher rebuild web_only.
Alternativamente, para ainda menos tempo de inatividade (variando entre 15 segundos e 2 minutos, conforme relatado):
./launcher bootstrap web_only
./launcher destroy web_only && ./launcher start web_only
Novamente, ao migrar para uma implantação com múltiplos contêineres, acompanhar quando isso é apropriado agora é sua responsabilidade. Você receberá notificações no console de Administração sobre atualizações, mas elas se aplicarão apenas ao contêiner web_only. Nada dirá quando você precisa atualizar o Postgres ou o Redis. Se fizer isso, leia a categoria de Anúncios antes de cada atualização de versão que fizer e leia as notas de lançamento para cada nova versão para a qual você está atualizando ou passando. Ou seja, se pular uma atualização de versão, não pule a leitura das notas de lançamento da versão que pulou. (Considere configurar um monitoramento nas notas de lançamento ou inscrever seu leitor de feeds em https://meta.discourse.org/tag/release-notes.rss para se manter atualizado.)
Note que reconstruir o contêiner web_only exige que o banco de dados esteja em execução, então você não pode acelerar as coisas reconstruindo todos os dois ou três contêineres em paralelo. Se for reconstruí-los todos a cada vez, mantenha-se com a implantação independente padrão recomendada; será mais rápido do que gerenciar múltiplos contêineres.
Revisão do Backup
Se você fizer backup dos uploads separadamente do banco de dados, espero que tenha um regime de backup remoto baseado em arquivos para os uploads, para que estejam sendo salvos para restauração em caso de desastre.
Revise sua implementação de backup remoto para garantir que ela fará backup dos uploads em /var/discourse/shared/web_only em vez de /var/discourse/shared/standalone, para que mantenha seus backups atualizados em sua nova implementação com múltiplos contêineres.