Tutoriais de VPS
Como fazer um simulado de restauração de backup de VPS (2026): restic, rclone, bancos de dados e volumes Docker em uma única passada
Ter backup de VPS não significa conseguir restaurar. Um plano de backup realmente confiável precisa rodar simulados de restauração periodicamente em uma máquina de teste limpa, confirmando que o repositório restic/rclone é legível, que os dumps de banco de dados podem ser importados, que os volumes Docker podem ser restaurados e que nenhuma configuração ou chave ficou de fora. Este artigo traz uma lista de verificação de simulado de restauração executável para o cenário mais comum de pequenos administradores de site: Docker + MySQL/PostgreSQL + diretórios de arquivos.

Muita gente diz que "tem backup", mas na verdade só empacota os arquivos todo dia e joga em um disco na nuvem.
Quando algo dá errado de verdade, descobre: os arquivos de backup podem ser baixados, mas o banco de dados não importa; os contêineres Docker sobem, mas faltam arquivos enviados no volume; docker-compose.yml não é encontrado; a senha do restic estava no VPS original, e quando a máquina some, a senha some junto.
Então o mais crítico em um backup não é "se o script roda", mas sim: você consegue restaurar o negócio em um VPS limpo?
Este artigo não trata dos sistemas complexos de recuperação de desastres das grandes empresas. Trata daquilo que todo usuário comum de VPS deveria fazer: rodar um simulado de restauração de tempos em tempos.
Antes do simulado de restauração, não saia digitando comandos. Primeiro defina duas métricas.
A primeira é o RPO, ou seja, quantos dados no máximo você pode perder. Por exemplo:
- Blog pessoal: perder 24 horas de posts e comentários é aceitável;
- Pequeno e-commerce: só pode perder alguns minutos de pedidos;
- Gitea / Git privado: o ideal é não perder nem um commit;
- Sistema de monitoramento: parte dos dados históricos pode ser perdida, mas a configuração não.
A segunda é o RTO, ou seja, em quanto tempo o serviço precisa ser restaurado.
Se sua meta é "restaurar um pequeno site WordPress em 2 horas", o simulado precisa ser cronometrado de verdade: desde ligar um VPS novo até o site abrir, o banco de dados funcionar, o painel administrativo permitir login e as imagens carregarem, quanto tempo leva no total?
Sem essas duas métricas, o backup é só consolo psicológico.
O que mais se esquece em um VPS comum são as configurações e as chaves, não os dados em si.
Sugiro montar primeiro uma lista:
| Tipo | Caminhos / conteúdo comuns | Como verificar durante o simulado |
|---|---|---|
| Arquivos do site | /var/www, /opt/app, diretórios de upload | Se a página inicial, o painel e as imagens funcionam |
| Bancos de dados | Dumps de MySQL, MariaDB, PostgreSQL | Se importam, número de tabelas e dados-chave corretos |
| Dados do Docker | volumes nomeados, bind mounts | Se os dados continuam lá após recriar o contêiner |
| Arquivos de configuração | docker-compose.yml, Nginx, Caddy, units do systemd | Se os serviços sobem do mesmo jeito que antes |
| Certificados e domínios | Certificados TLS, DNS, configuração do Cloudflare | Se o HTTPS funciona |
| Chaves | .env, chaves de API, senha do restic, config do rclone | Se dá para descriptografar e restaurar sem depender do VPS original |
Alguns diretórios não precisam de backup:
/tmp/proc/sys/run/dev/var/cache- O
node_modulesdo projeto - Imagens e arquivos temporários que podem ser reconstruídos
O que realmente precisa de backup é "o que não pode ser regenerado a partir do código-fonte ou do gerenciador de pacotes".
Este é o motivo número um de falhas de backup em VPS.
Quando bancos como MySQL e PostgreSQL estão em execução, empacotar diretamente /var/lib/mysql ou o diretório de dados do PostgreSQL pode não gerar dados consistentes. Você acha que fez backup, mas a restauração pode quebrar.
Para MySQL / MariaDB use:
mysqldump --all-databases \
--single-transaction \
--quick \
--routines \
-u root -p \
| gzip > /var/backups/db/mysql-all-$(date +%F-%H%M).sql.gz
Para PostgreSQL use:
sudo -u postgres pg_dumpall | gzip > /var/backups/db/postgres-all-$(date +%F-%H%M).sql.gz
Se for um único banco, também pode usar:
pg_dump -U app_user -d app_db -Fc > /var/backups/db/app_db-$(date +%F-%H%M).dump
O ponto aqui não é quão bonitos são os comandos, mas que você importe de verdade uma vez durante o simulado.
Teste de restauração do MySQL:
gunzip < mysql-all-2026-06-11-0200.sql.gz | mysql -u root -p
Teste de restauração do PostgreSQL:
createdb app_db_test
pg_restore -U app_user -d app_db_test app_db-2026-06-11-0200.dump
Se a importação falhar, seu plano de backup não está à altura.
Projetos com Docker são os mais fáceis de julgar errado: contêineres podem ser apagados, imagens podem ser baixadas de novo, mas os dados nos volumes não.
Primeiro liste os volumes:
docker volume ls
Veja a localização real de um volume:
docker volume inspect myapp_data
Se o volume só guarda arquivos enviados, anexos estáticos ou estado de configuração, você pode empacotá-lo com um contêiner temporário:
docker run --rm \
-v myapp_data:/source:ro \
-v /var/backups/docker:/backup \
alpine:latest \
tar czf /backup/myapp_data-$(date +%F-%H%M).tar.gz -C /source .
Restaurar para um volume novo:
docker volume create myapp_data
docker run --rm \
-v myapp_data:/target \
-v /var/backups/docker:/backup:ro \
alpine:latest \
tar xzf /backup/myapp_data-2026-06-11-0200.tar.gz -C /target
Mas se o volume guarda dados de banco de dados, não faça tar diretamente de um volume em execução. Prefira mysqldump, pg_dump ou as ferramentas de exportação da própria aplicação.
Se o backup em nível de arquivo for inevitável, ao menos pare o contêiner ou entre em uma janela de manutenção.
rclone copy é ótimo para enviar arquivos de backup para armazenamento de objetos, mas por si só não é um sistema de backup completo. Uma abordagem mais robusta é:
- o restic cuida da criptografia, deduplicação, snapshots e política de retenção;
- o rclone cuida da conexão com diferentes armazenamentos na nuvem;
- os bancos de dados são exportados primeiro;
- os volumes Docker são tratados conforme o tipo;
- testes de restauração são executados periodicamente.
Inicializar o repositório restic:
export RESTIC_REPOSITORY=s3:https://s3.example.com/vps-backups
export RESTIC_PASSWORD='请放到密码管理器,不要只放在 VPS 上'
restic init
Executar um backup:
restic backup \
/var/www \
/opt/app \
/etc/nginx \
/etc/caddy \
/etc/systemd/system \
/var/backups/db \
/var/backups/docker \
--exclude 'node_modules' \
--exclude '.git'
Definir a política de retenção:
restic forget \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 3 \
--prune
Verificar o repositório:
restic check
restic snapshots
Um erro comum é executar só forget sem --prune. Assim os snapshots antigos somem da lista, mas os dados subjacentes podem não ser realmente liberados, e a conta de armazenamento continua subindo.
Um simulado mínimo viável não precisa afetar a produção.
Você pode abrir um VPS temporário ou usar uma máquina virtual local e executar nesta ordem:
- Instalar o ambiente base: Docker, Docker Compose, banco de dados, Nginx/Caddy;
- Configurar o acesso do restic/rclone ao repositório de backup;
restic restore latest --target /tmp/restore-test;- Restaurar arquivos do site, arquivos de configuração, dumps de banco de dados, volumes Docker;
- Acessar por um domínio temporário ou arquivo hosts;
- Verificar login, uploads, consultas, painel administrativo, tarefas agendadas;
- Registrar o tempo total do início até o serviço ficar disponível.
Restaurar o snapshot mais recente:
restic restore latest --target /tmp/restore-test
Restaurar apenas um caminho específico:
restic restore latest --include /var/www --target /
Depois de restaurar, não basta ver se os arquivos existem; é preciso rodar verificações de negócio:
curl -I https://test.example.com
curl -s https://test.example.com/health
sudo systemctl status nginx --no-pager
docker compose ps
Se for WordPress, verifique pelo menos:
- A página inicial abre;
- O painel administrativo permite login;
- As imagens da biblioteca de mídia aparecem;
- A quantidade de posts no banco de dados está correta;
- Os plugins não dão erro por causa de caminhos ou permissões.
Se for Gitea, verifique pelo menos:
- A lista de repositórios;
- git clone;
- A porta SSH;
- Se os runners / Actions precisam ser registrados de novo.
Se for uma aplicação própria, verifique pelo menos:
- Se as
.envestão completas; - O status das migrações do banco de dados;
- Se as filas foram iniciadas;
- Se o diretório de upload é gravável;
- Se as tarefas agendadas foram restauradas.
Depois do simulado de restauração, deixe documentação. Caso contrário, na próxima vez que algo der errado, você ainda vai depender da memória.
Um runbook mínimo deve incluir pelo menos:
# VPS 恢复演练记录
- 演练日期:2026-06-11
- 备份快照:restic snapshot abc123
- 备份时间点:2026-06-11 02:00
- 测试机器:Ubuntu 24.04 / 2C4G
- 恢复耗时:58 分钟
- 恢复内容:网站文件、Nginx 配置、MySQL dump、Docker volumes
- 验证结果:首页 OK、后台 OK、上传 OK、数据库记录数 OK
- 发现问题:.env 缺少第三方 API key,已补入密码管理器
- 下次改进:把 docker-compose.yml 放入 Git 仓库
Você vai perceber que o primeiro simulado normalmente expõe problemas. Por exemplo:
- O script de backup não fazia backup de
.env; - A senha do restic só existe na máquina original;
- A config do rclone não foi salva fora do site;
- O arquivo de dump do banco de dados está vazio;
- Os nomes dos volumes Docker não batem com o arquivo compose;
- A configuração do Nginx referencia um caminho de certificado que não existe;
- As permissões do bucket de armazenamento de objetos não foram restauradas.
Encontrar esses problemas durante o simulado é bom; encontrá-los no dia da falha é um desastre.
O cron não dar erro não significa que o backup deu certo. Pode ser que nem tenha executado, ou que tenha falhado no meio.
O script de backup deve fazer pelo menos três coisas:
set -euo pipefail
Assim o script sai imediatamente ao encontrar erro, em vez de fingir que deu certo.
Depois verifique o horário do último backup:
restic snapshots | tail
Se você tem monitoramento, adicione um alerta para "backup sem atualização há mais de 24 horas". Sem monitoramento, ao menos se avise por e-mail, Telegram, Uptime Kuma push monitor ou algo parecido.
Se você já tem um sistema de monitoramento, pode combinar com este artigo:
Fazer uma vez por trimestre já basta para muitos sites pequenos:
- Listar o snapshot mais recente do repositório restic/rclone;
- Restaurar o snapshot mais recente em um diretório temporário;
- Conferir por amostragem arquivos de configuração importantes e arquivos enviados;
- Importar os dumps de MySQL/PostgreSQL em um banco de teste;
- Restaurar pelo menos um volume Docker;
- Subir o negócio no ambiente de teste com compose;
- Acessar a página inicial, o painel e o endpoint de health check;
- Registrar o tempo de restauração;
- Verificar chaves, configurações e certificados faltantes;
- Atualizar o runbook.
Se o seu negócio for mais importante, você pode fazer um simulado leve todo mês e um completo a cada trimestre.
Não. Snapshots servem para reverter rápido antes de uma mudança, mas não substituem backups fora do site. Se a conta do provedor for bloqueada, a máquina for apagada por engano, uma região falhar ou o snapshot corromper, o snapshot e a máquina podem sumir juntos.
Se você ainda não distingue snapshot, backup e imagem, leia primeiro:
Não. O sucesso do backup só significa que "alguns dados foram gravados", não que esses dados possam ser restaurados em um negócio utilizável. A verificação real é restaurar + iniciar + acessar + validar dados.
Não é recomendado. Arquivos de banco em execução podem estar em estado inconsistente. Com MySQL/MariaDB, usar mysqldump --single-transaction é mais estável; com PostgreSQL, pg_dump ou pg_dumpall.
Não só no VPS. No mínimo, coloque em um gerenciador de senhas e prepare um backup offline. O repositório restic é criptografado; se a senha for perdida, o backup basicamente deixa de existir.
Não necessariamente. Um simulado leve pode usar um domínio de teste ou arquivo hosts. Um simulado completo de recuperação de desastres pode simular a troca de DNS, mas cuidado para não afetar o tráfego de produção.
O backup de VPS não termina com "rodar um script uma vez por dia".
A cadeia realmente confiável deve ser: exportar primeiro o banco de dados, colocar arquivos e configurações em backups criptografados, manter o repositório de backup fora do site, ter uma política de retenção controlável e, por fim, restaurar periodicamente em um ambiente limpo.
Se agora você só pode fazer uma coisa — nem trocar de ferramenta, nem comprar armazenamento mais caro —, que seja encontrar um VPS temporário e rodar um simulado de restauração completo. Só depois que funcionar você vai saber se o seu backup é de fato um backup.