Backups
Backup diário do PostgreSQL de staging no Garage, a verificação e a restauração.
O PostgreSQL de staging tem backup diário no Garage v2.4.1, um armazenamento compatível com S3 que roda como duas aplicações a mais no mesmo servidor do Dokploy (NOVA-119). A escolha do Garage em vez do MinIO: um binário pequeno, com modo de nó único documentado e uma API de administração para criar o bucket e a chave por script. A imagem dele não tem shell, por isso a configuração inicial é um job separado.
As peças
| Peça | O que é |
|---|---|
garage | dxflrs/garage:v2.4.1, um nó (replication_factor = 1), metadados em SQLite, dois volumes (metadados e dados), atualização stop-first: duas tarefas no mesmo volume de metadados o corromperiam |
garage.toml | Commitado sem segredos; o segredo de RPC e o token de administração vêm do ambiente do Dokploy, gerados uma vez pelo apply e nunca impressos |
| API S3 (porta 3900) | A única parte pública: https://s3.novahml.com (Let's Encrypt), path-style, região garage |
| API de administração (porta 3903) | Sem domínio: alcançável só na rede interna do swarm |
garage-init | Job one-shot (curlimages/curl): define o layout do nó quando ele não tem um, importa a chave de backup que o apply gerou, cria o bucket monalisa-staging-backups e dá à chave leitura e escrita só nesse bucket |
Destino garage-staging | Destino S3 do Dokploy, com essa chave |
| Backup do PostgreSQL | pg_dump -Fc do banco, compactado, todo dia às 03:00 UTC pelo agendador do Dokploy, mantendo as 14 cópias mais recentes |
O que os backups cobrem
Os backups ficam só no servidor (VPS) do banco. Eles protegem contra erros lógicos (uma migration ruim, um DELETE
errado, uma versão quebrada) e permitem voltar staging a um dia anterior. Não protegem contra a perda do servidor
ou do disco: não há cópia fora dele, por decisão, porque os dados de staging podem ser reconstruídos.
O Valkey e o ElasticMQ não têm backup. O Valkey guarda só caches, portões de idempotência e sinais de despertar, e pode começar vazio; as filas do ElasticMQ são em memória.
Num servidor novo
dokploy:applydeclaragarage,garage-init, volumes, montagens, domínio e segredos, e avisa que os backups esperam ogarage-init.dokploy:deploysobe o Garage e roda ogarage-initdepois da versão (ver Staging no Dokploy), conferindo que ele terminaComplete.- O
applyseguinte cria o destino com a chave dogarage-init, faz o Dokploy testar a conexão listando o bucket e agenda o backup. Bucket e chave só existem depois dogarage-init, e um destino não testado só falharia às 03:00.
O DNS do domínio S3 precisa apontar para o servidor antes do primeiro apply que o usa, para o Let's Encrypt emitir o
certificado. Uma mudança em garage.toml só vale depois de republicar o garage na interface; uma mudança no script do
garage-init roda com dokploy:deploy --reinit.
Para trocar a chave de backup: remova as duas variáveis da chave do ambiente do garage-init, rode apply (gera um par
novo), deploy --reinit (importa) e apply (atualiza o destino), e então apague a chave antiga no Garage, ou ao menos
retire o acesso dela ao bucket; o Garage a mantém, com os direitos, até lá.
Verificar: dokploy:backup-check
bun run dokploy:backup-checkO comando dispara o backup agendado na hora e confere que um arquivo .sql.gz novo e não vazio chegou ao bucket,
imprimindo a chave e o tamanho dele.
Restaurar
O Dokploy só oferece restauração pela interface (não há endpoint de API), então o teste é manual, num banco de rascunho:
- Rode
dokploy:backup-checke anote o arquivo que ele imprimiu. - No servidor, crie um banco de rascunho no contêiner do PostgreSQL (
createdb … monalisa_restore_check). - Na interface do Dokploy (staging › postgres › Backups › Restore), escolha o destino
garage-staging, o arquivo e o bancomonalisa_restore_check. O Dokploy rodapg_restore -O --clean --if-existsnesse banco. - Compare com o banco original:
- a migration mais nova (
select name from mikro_orm_migrations order by id desc limit 1) deve ser igual aolatestMigrationdo/ready; - o número de tabelas (
select count(*) from information_schema.tables where table_schema = 'public') deve ser igual ao do bancomonalisa.
- a migration mais nova (
- Apague o banco de rascunho (
dropdb).
Restaurar sobre o próprio monalisa é a mesma ação na interface, com o nome monalisa: pare a API e os workers antes.
Uma restauração foi testada em 2026-10-09: o banco restaurado tinha as 82 tabelas e as migrations até
0017_authorization-scope-ceiling-locks.