Problemas de restauração

Com base no repositório discourse_docker, escrevi um pequeno script para automatizar seu uso dentro de uma máquina Vagrant (execute com set -x para ver o que está sendo feito na prática)

Será que copiei o backup para o local errado?

E o que significa a linha de log
Garantindo que /var/www/discourse/tmp/restores/default/2020-05-13-190832 existe...?

~/infra/discourse no  master! ⌚ 21:14:07
$ pwd
/home/pihentagy/infra/discourse
~/infra/discourse no  master! ⌚ 21:01:14
$ ./wl.sh start
+ set -e
+ VAGRANT_MACHINE_NAME=guest
+ cd discourse
+ case "$1" in
+ init
+ printf 'Checkout e atualização do repositório…\n'
Checkout e atualização do repositório…
+ cd ..
+ git clone https://github.com/discourse/discourse_docker.git discourse
fatal: o caminho de destino 'discourse' já existe e não é um diretório vazio.
+ printf 'Repositório já está lá\n'
Repositório já está lá
+ cd discourse
+ printf 'Atualizando repositório…\n'
Atualizando repositório…
+ git pull -r
remote: Enumerando objetos: 6, concluído.
remote: Contando objetos: 100% (6/6), concluído.
remote: Comprimindo objetos: 100% (4/4), concluído.
remote: Total 6 (delta 2), reutilizados 5 (delta 2), pack-reutilizados 0
Descompactando objetos: 100% (6/6), concluído.
De https://github.com/discourse/discourse_docker
   3e465a2..49ed141  master     -> origin/master
Autostash criado: 36aae80
HEAD agora está em 3e465a2 Remover todos os rastros do pg12 para que o pg_wrapper não fique confuso
Primeiro, retrocedendo o HEAD para reexecutar seu trabalho sobre ele...
Master avançado rapidamente para 49ed14152971f7f4a7437657987952be44c33c0a.
A aplicação do autostash resultou em conflitos.
Suas alterações estão seguras no stash.
Você pode executar "git stash pop" ou "git stash drop" a qualquer momento.
+ printf 'Copiando arquivo de configuração…\n'
Copiando arquivo de configuração…
+ cp ../resources/discourse.yml containers/
+ echo 'Iniciando máquina Vagrant...'
Iniciando máquina Vagrant...
+ vagrant up
Levando a máquina 'dockerhost' com o provedor 'virtualbox'...
==> dockerhost: Verificando se a caixa 'ubuntu/xenial64' está atualizada...
==> dockerhost: A máquina já está provisionada. Execute `vagrant provision` ou use a flag `--provision`
==> dockerhost: para forçar o provisionamento. Os provisionadores marcados para rodar sempre ainda serão executados.
+ vagrant ssh -c 'cd /vagrant;sudo ./launcher start discourse'
2627afdfbaac
Nada a fazer, seu contêiner já foi iniciado!
Conexão com 127.0.0.1 fechada.
+ exit 0

~/infra/discourse no  master! ⌚ 21:07:56
$ ./wl.sh restore /home/pihentagy/infra/icontest-2020-05-12-033823-v20200506044956.tar.gz
+ set -e
+ VAGRANT_MACHINE_NAME=guest
+ cd discourse
+ case "$1" in
+ shift
+ backup=/home/pihentagy/infra/icontest-2020-05-12-033823-v20200506044956.tar.gz
+ discourse_backup_dir=shared/standalone/backups/default
+ mkdir --parents shared/standalone/backups/default
+ rsync -P --verbose /home/pihentagy/infra/icontest-2020-05-12-033823-v20200506044956.tar.gz shared/standalone/backups/default
icontest-2020-05-12-033823-v20200506044956.tar.gz
    390.774.609 100%  317,41MB/s    0:00:01 (xfr#1, to-chk=0/1)

enviado 390.870.133 bytes recebido 35 bytes 156.348.067,20 bytes/segundo
tamanho total é 390.774.609  aceleração é 1,00
+ vagrant ssh -c 'sudo docker exec -w /var/www/discourse -i discourse discourse enable_restore'
Restauração agora permitida. Desative com `disable_restore`
Conexão com 127.0.0.1 fechada.
+ vagrant ssh -c 'sudo docker exec -w /var/www/discourse -i discourse discourse restore'
Você deve fornecer um nome de arquivo para restaurar. Você quis dizer um dos seguintes?

Conexão com 127.0.0.1 fechada.
+ vagrant ssh -c 'sudo docker exec -w /var/www/discourse -i discourse discourse restore icontest-2020-05-12-033823-v20200506044956.tar.gz'
Iniciando restauração: icontest-2020-05-12-033823-v20200506044956.tar.gz
[INICIADO]
'system' iniciou a restauração!
Marcando restauração como em execução...
Garantindo que /var/www/discourse/tmp/restores/default/2020-05-13-190832 existe...
Copiando arquivo compactado para o diretório tmp...
EXCEÇÃO: lib/discourse.rb:90:in `exec': Falha ao copiar arquivo compactado para o diretório tmp.
cp: não é possível obter estatísticas de '/var/www/discourse/public/backups/default/icontest-2020-05-12-033823-v20200506044956.tar.gz': Arquivo ou diretório inexistente
lib/discourse.rb:100:in `execute_command'
lib/discourse.rb:90:in `exec'
lib/discourse.rb:40:in `execute_command'
/var/www/discourse/lib/backup_restore/local_backup_store.rb:42:in `download_file'
/var/www/discourse/lib/backup_restore/backup_file_handler.rb:61:in `copy_archive_to_tmp_directory'
/var/www/discourse/lib/backup_restore/backup_file_handler.rb:21:in `decompress'
/var/www/discourse/lib/backup_restore/restorer.rb:42:in `run'
script/discourse:143:in `restore'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/thor-1.0.1/lib/thor/base.rb:485:in `start'
script/discourse:284:in `<top (required)>'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:63:in `load'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:63:in `kernel_load'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:28:in `run'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli.rb:476:in `exec'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor.rb:399:in `dispatch'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli.rb:30:in `dispatch'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/base.rb:476:in `start'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli.rb:24:in `start'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/exe/bundle:46:in `block in <top (required)>'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/friendly_errors.rb:123:in `with_friendly_errors'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/exe/bundle:34:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tentando reverter...
Não houve necessidade de reverter
Limpando arquivos...
Removendo diretório tmp '/var/www/discourse/tmp/restores/default/2020-05-13-190832'...
Retomando sidekiq...
Marcando restauração como concluída...
Notificando 'system' sobre o fim da restauração...
Concluído!
[FALHOU]
Restauração finalizada.
Conexão com 127.0.0.1 fechada.

O vagrant não é suportado, mas aqui vai um conselho de qualquer forma. :wink:

Não tenho certeza de como o rsync funciona. O caminho precisa terminar com uma barra? Se o arquivo for para o diretório correto, verifique se o arquivo copiado pode ser lido pelo servidor.

Então, o vagrant (virtualbox) pode causar alguns problemas?

~/infra/discourse on  master! ⌚ 23:22:23
$ tree discourse/shared 
discourse/shared
└── standalone
    └── backups
        └── default
            └── icontest-2020-05-12-033823-v20200506044956.tar.gz

3 diretórios, 1 arquivo

~/infra/discourse on  master! ⌚ 23:22:27
$ ls discourse/shared/standalone/backups/default 
icontest-2020-05-12-033823-v20200506044956.tar.gz

~/infra/discourse on  master! ⌚ 23:22:36
$ ls -l discourse/shared/standalone/backups/default
total 381620
-rw-r--r-- 1 pihentagy pihentagy 390774609 May 13 21:08 icontest-2020-05-12-033823-v20200506044956.tar.gz

Parece que o arquivo é legível por todos e está no local correto. De dentro do contêiner Docker discourse, onde devo ver o backup? Meu script de restauração automática está correto ou devo copiar para dentro do contêiner Docker? Se sim, onde? (Talvez haja algum guia sobre como automatizar o Discourse de fora [do Docker?])

+ vagrant ssh -c 'sudo docker exec -w /var/www/discourse -i discourse discourse restore'
Você deve fornecer um nome de arquivo para restaurar. Você quis dizer um dos seguintes?

A conexão com 127.0.0.1 foi encerrada.
+ vagrant ssh -c 'sudo docker exec -w /var/www/discourse -i discourse discourse restore icontest-2020-05-12-033823-v20200506044956.tar.gz'
Iniciando a restauração: icontest-2020-05-12-033823-v20200506044956.tar.gz
[

Não é obrigatório, mas não terminar o caminho com uma barra é uma má prática, pois o resultado depende de o diretório já existir ou não.

Se o diretório de destino já existir, não é necessário incluir a barra e o arquivo será copiado para dentro do diretório.
Se o diretório de destino não existir e não houver barra no final, o arquivo será copiado para um arquivo chamado ‘default’.
Se o diretório de destino não existir e houver uma barra no final, o diretório será criado e o arquivo será copiado para dentro dele.

Neste caso, a cópia parece ter funcionado bem (por sorte).

No entanto,

Como não há sugestões após “você quis dizer um dos seguintes?”, o arquivo não está no local correto. Parece que as unidades estão mapeadas incorretamente para o contêiner Docker.

Você pode iniciar um backup de dentro do Docker (discourse backup) e ver onde ele acaba sendo salvo no seu sistema de arquivos host.

Estranhamente, ele não está visível no sistema de arquivos do host. Deveria estar?

vagrant@ubuntu-xenial:~$ sudo docker exec -w /var/www/discourse -i discourse discourse backup
Iniciando backup...
[INICIADO]
'system' iniciou o backup!
Marcando backup como em execução...
Garantindo que '/var/www/discourse/tmp/backups/default/2020-05-14-121930' exista...
Garantindo que '/var/www/discourse/public/backups/default' exista...
Atualizando metadados...
Pausando sidekiq...
Aguardando o sidekiq terminar de executar as tarefas...
Dumpando o esquema público do banco de dados...


Muitos comandos pg_dump"

Retomando sidekiq...
Finalizando backup...
Criando arquivo: discourse-2020-05-14-121930-v20200512064023.tar.gz
Garantindo que o arquivo já não exista...
Criando arquivo vazio...
Arquivando o dump de dados...
Arquivando uploads...
Removendo diretório tmp '/var/www/discourse/tmp/backups/default/2020-05-14-121930'...
Comprimindo arquivo com gzip, isso pode levar um tempo...
Executando o after_create_hook para o backup...
Excluindo backups antigos...
Limpeza de arquivos...
Removendo resíduos '.tar'...
Marcando backup como finalizado...
Atualizando estatísticas de disco...
Concluído!
[SUCESSO]
Backup concluído.
Arquivo de saída está em: /var/www/discourse/public/backups/default/discourse-2020-05-14-121930-v20200512064023.tar.gz

vagrant@ubuntu-xenial:~$ find / -name discourse-2020-05-14-121930-v20200512064023.tar.gz 2>/dev/null
vagrant@ubuntu-xenial:~$ sudo docer exec -w /var/www/discourse -i discourse discourse enable_restore
sudo: docer: comando não encontrado
vagrant@ubuntu-xenial:~$ sudo docker exec -w /var/www/discourse -i discourse discourse enable_restore
Restauração agora permitida. Desative com `disable_restore`
vagrant@ubuntu-xenial:~$ sudo docker exec -w /var/www/discourse -i discourse discourse restore
Você deve fornecer um nome de arquivo para restaurar. Você quis dizer um dos seguintes?

discourse restore discourse-2020-05-14-121930-v20200512064023.tar.gz
discourse restore discourse-2020-05-14-121710-v20200512064023.tar.gz
discourse restore discourse-2020-05-14-120436-v20200512064023.tar.gz

Off: existe alguma forma de destacar linhas em blocos de código?

```bash

O padrão aqui é texto. Acredito que o padrão para novas instalações seja ‘adivinhar a linguagem’,

Queria dizer ‘olha só, a linha 5 é importante!’, ou seja, destacar linha(s) específica(s).

Bem, normalmente /var/discourse/shared/standalone/backups é o diretório que é visível no seu container como /var/www/discourse/public/backups (daí a palavra shared). Seu comando rsync está colocando o backup dentro desse diretório para torná-lo acessível de dentro do container.

Vice-versa, se o container escrever em public/backups, ele deve ser visível no seu host no diretório compartilhado.

Eu escrevi /var/discourse/shared... acima. Mas parece que você está trabalhando em ~/infra/discourse, então você está copiando para ~/infra/discourse/shared/standalone/backups/default.

Normalmente, o container é mapeado para /var/discourse/shared/...

Isso pode ser o problema. Você pode verificar se existe um /var/discourse/shared?

Não. Você não pode fazer isso em um bloco de código, pois tudo é apresentado exatamente como está.

Bom, agora fiz um backup e verifiquei se ele pode ser encontrado fora da máquina Docker, mas não pode.

vagrant@ubuntu-xenial:~$ sudo docker inspect -f "{{.Mounts}}" discourse
[{bind  /var/discourse/shared/standalone /shared   true rprivate} {bind  /var/discourse/shared/standalone/log/var-log /var/log   true rprivate}]

Verdade, mas ignorei isso por enquanto. Aliás, aquele rsync foi feito fora da máquina (vagrant) onde executei meu Discourse.

Mas, por enquanto, como você sugeriu, fiz o seguinte:

  • vagrant ssh na máquina e, de dentro dela:
    • fiz um backup com sudo docker exec -w /var/www/discourse -i discourse discourse backup
    • observei o caminho do arquivo:
      Arquivo de saída está em: /var/www/discourse/public/backups/default/discourse-2020-05-14-125606-v20200512064023.tar.gz
      
    • pesquisei toda a máquina vagrant por aquele arquivo específico, mas não encontrei nada
      find / -name discourse-2020-05-14-125606-v20200512064023.tar.gz 2>/dev/null
      
    • no entanto, se eu entrar na máquina Docker, ele está lá
      root@ubuntu-xenial-discourse:/var/www/discourse/public/backups/default# ls
      discourse-2020-05-14-120436-v20200512064023.tar.gz  discourse-2020-05-14-121930-v20200512064023.tar.gz
      discourse-2020-05-14-121710-v20200512064023.tar.gz  discourse-2020-05-14-125606-v20200512064023.tar.gz
      

Então minha pergunta: se eu criar um backup, devo vê-lo fora do Docker?

Enquanto isso, acabei de criar uma máquina vagrant e fazer um git clone de dentro dela no diretório padrão /var/discourse. A única “estranheza” é que tenho um discourse.yml dentro do contêiner, não um app.yml.

Sim, e isso é a mesma coisa que o seu problema original:
“se você tem um backup fora do Docker e o coloca no diretório compartilhado, você deve vê-lo dentro do Docker” (e você não vê).

O problema está nos seus diretórios compartilhados e é por causa disso:

Quero dizer: por enquanto, recriei uma máquina Vagrant totalmente nova, sem copiar nenhum backup anterior. Fiz o bootstrap e iniciei o contêiner Docker. Depois, fiz o backup.

Nada é visível na máquina Vagrant fora da máquina Docker.

Acho que encontrei o problema: montei esta pasta compartilhada do Docker na máquina Vagrant que a contém.

config.vm.synced_folder "discourse/", "/var/discourse"

Se eu comentar isso no meu Vagrantfile, os backups “magicamente” aparecem.

Então, o problema era que a pasta compartilhada do Vagrant (para “up”) e a pasta compartilhada do Docker (para “down”) entravam em conflito, tornando tudo inválido.