Backup e restauração

Gere backups verificados do banco e sincronize arquivos persistentes do OpenDataBio sem duplicar o grande storage no servidor da aplicação.

Um backup do OpenDataBio tem duas partes: o dump lógico do banco e os arquivos persistentes referenciados por ele. As ferramentas fornecidas propositalmente não compactam nem duplicam o storage de mídias no servidor da aplicação. Elas criam snapshots pequenos e verificados do banco e permitem que uma estação do administrador, NAS ou servidor de backup baixe os arquivos atuais por rsync incremental.

Manter somente dumps do banco no servidor da aplicação é uma proteção mínima, não uma recuperação de desastre. Se o servidor ou disco for perdido, o storage original também será perdido. Sempre que possível, baixe ou envie regularmente uma segunda cópia para outra máquina.

O que deve ser protegido

Guarde em conjunto:

  1. o banco MySQL/MariaDB;
  2. storage/app/public/media;
  3. storage/app/public/datasets, incluindo versões publicadas de datasets;
  4. arquivos de ambiente e secrets de produção em local seguro separado;
  5. especialmente APP_KEY, necessária para descriptografar valores armazenados pela aplicação, como chaves pessoais do Pl@ntNet.

Redis, caches, sessões, logs, vendor, node_modules e downloads regeneráveis não fazem parte do backup durável.

Ferramentas incluídas

O repositório fornece:

scripts/backup/
├── backup-opendatabio.sh
├── backup.env.example
├── pull-opendatabio-backup.sh
├── pull.env.example
├── verify-opendatabio-backup.sh
└── systemd/

backup-opendatabio.sh roda no servidor da aplicação. Ele cria e verifica o dump comprimido, grava checksums e manifesto, marca o snapshot como COMPLETE e atualiza LATEST atomicamente. Nunca copia ou apaga o storage.

pull-opendatabio-backup.sh roda em outra máquina. Ele baixa o último snapshot completo do banco e sincroniza media e datasets diretamente dos diretórios originais.

Configurar o servidor da aplicação

Crie uma configuração pertencente ao root:

sudo install -d -m 700 /etc/opendatabio /var/backups/opendatabio
sudo cp scripts/backup/backup.env.example /etc/opendatabio/backup.env
sudo chmod 600 /etc/opendatabio/backup.env
sudo editor /etc/opendatabio/backup.env

Informe os caminhos reais do checkout e do backup. O destino deve ser absoluto e diferente de /.

Produção com Docker

Use:

ODB_DEPLOYMENT=docker
ODB_INSTALL_ROOT=/opt/opendatabio
ODB_ENV_FILE=/opt/opendatabio/.env.production
ODB_COMPOSE_FILE=/opt/opendatabio/docker-compose.prod.yml
ODB_COMPOSE_PROJECT=odb-prod
ODB_BACKUP_ROOT=/var/backups/opendatabio
ODB_BACKUP_GROUP=
ODB_STORAGE_PATH=/srv/opendatabio/storage

Por padrão, o Docker usa o volume nomeado odbstorage. Um cliente rsync remoto não consegue acessar com segurança os arquivos dentro desse volume privado. Em uma nova produção que usará backup pull, prepare um diretório no host:

sudo install -d -m 755 /srv/opendatabio/storage

Antes da primeira inicialização, defina no .env.production:

ODB_STORAGE_SOURCE=/srv/opendatabio/storage

Os serviços Compose montam o diretório no local normal da aplicação, e o entrypoint do container aplica o proprietário www-data configurado na imagem. Não fixe UID/GID no host, pois os parâmetros de build podem alterá-los. Instalações existentes que usam volume nomeado devem copiar seu conteúdo para o bind mount durante uma manutenção planejada antes de alterar ODB_STORAGE_SOURCE. Não troque apenas a variável, pois os arquivos parecerão ausentes.

Instalação nativa com Apache/nginx

Use:

ODB_DEPLOYMENT=native
ODB_INSTALL_ROOT=/var/www/opendatabio
ODB_BACKUP_ROOT=/var/backups/opendatabio
ODB_DB_NAME=opendatabio
ODB_DB_DEFAULTS_FILE=/root/.opendatabio-backup.cnf
ODB_BACKUP_GROUP=
ODB_STORAGE_PATH=/var/www/opendatabio/storage/app/public

Armazene as credenciais fora do script:

[client]
host=localhost
port=3306
user=opendatabio_backup
password=SUBSTITUA_POR_SENHA_PRIVADA
sudo chmod 600 /root/.opendatabio-backup.cnf

O usuário precisa de leitura suficiente para exportar tabelas e triggers. A senha não é passada como argumento de comando no host.

Executar e verificar

Teste manualmente antes de agendar:

sudo /opt/opendatabio/scripts/backup/backup-opendatabio.sh \
  /etc/opendatabio/backup.env

Resultado:

/var/backups/opendatabio/
├── LATEST
└── snapshots/20260813T021700Z/
    ├── database.sql.gz
    ├── SHA256SUMS
    ├── manifest.env
    └── COMPLETE

Verifique independentemente:

sudo scripts/backup/verify-opendatabio-backup.sh \
  /var/backups/opendatabio/snapshots/20260813T021700Z

Somente diretórios com COMPLETE entram na retenção automática. O padrão mantém sete dias de dumps. Ajuste ODB_RETENTION_DAYS conforme necessário.

Agendar no servidor

Timer do systemd (recomendado)

sudo cp scripts/backup/systemd/opendatabio-backup.service.example \
  /etc/systemd/system/opendatabio-backup.service
sudo cp scripts/backup/systemd/opendatabio-backup.timer.example \
  /etc/systemd/system/opendatabio-backup.timer
sudo systemctl daemon-reload
sudo systemctl enable --now opendatabio-backup.timer
sudo systemctl list-timers opendatabio-backup.timer

Consulte execuções:

sudo systemctl status opendatabio-backup.service
sudo journalctl -u opendatabio-backup.service

Persistent=true executa um backup perdido após o servidor voltar.

Alternativa com cron

Edite com sudo crontab -e:

17 2 * * * /opt/opendatabio/scripts/backup/backup-opendatabio.sh /etc/opendatabio/backup.env >> /var/log/opendatabio-backup.log 2>&1

Liste agendamentos:

sudo crontab -l
sudo ls -la /etc/cron.d /etc/cron.daily
sudo systemctl list-timers --all

O script usa flock; execuções sobrepostas falham com segurança.

Baixar para uma máquina do administrador

Instale openssh-client e rsync na estação, NAS ou servidor receptor. Use um usuário SSH que possa apenas ler os diretórios de backup e storage. Prefira chave SSH dedicada e valide a chave de host do servidor.

No servidor da aplicação, crie o grupo configurado e adicione o usuário SSH:

sudo groupadd --system opendatabio-backup
sudo usermod -aG opendatabio-backup backup-reader

Depois defina ODB_BACKUP_GROUP=opendatabio-backup em backup.env e gere um novo backup para aplicar as permissões de grupo ao snapshot concluído.

backup-opendatabio.sh dá ao grupo acesso de leitura apenas aos snapshots concluídos e a LATEST. Separadamente, permita leitura e travessia de media e datasets com grupo ou ACL apropriado; não torne configurações privadas legíveis para todos.

sudo install -d -m 700 /etc/opendatabio /srv/backups/opendatabio
sudo cp scripts/backup/pull.env.example /etc/opendatabio/pull-backup.env
sudo chmod 600 /etc/opendatabio/pull-backup.env
sudo editor /etc/opendatabio/pull-backup.env

Valores principais:

ODB_REMOTE_HOST=backup-reader@example.org
ODB_REMOTE_BACKUP_ROOT=/var/backups/opendatabio
ODB_REMOTE_STORAGE_ROOT=/srv/opendatabio/storage
ODB_LOCAL_ROOT=/srv/backups/opendatabio
ODB_SSH_IDENTITY=/home/admin/.ssh/opendatabio-backup
ODB_STORAGE_POLICY=archive

Teste:

scripts/backup/pull-opendatabio-backup.sh \
  /etc/opendatabio/pull-backup.env

O cliente lê LATEST no servidor em vez de adivinhar uma pasta pela data local. Ele reutiliza uma conexão SSH, valida checksum e gzip e executa rsync incremental diretamente no storage original. Não usa compressão, pois imagens e muitos arquivos de datasets já estão comprimidos.

Políticas:

  • archive (padrão) nunca apaga localmente um arquivo ausente no servidor;
  • mirror iguala a cópia atual, mas move removidos ou substituídos para history/SNAPSHOT/ em vez de descartá-los.

Não adicione --delete simples sem snapshot ou diretório de preservação. Uma exclusão acidental na aplicação seria propagada ao backup.

Os exemplos opendatabio-backup-pull.service.example e opendatabio-backup-pull.timer.example podem ser instalados e ajustados na máquina receptora. Persistent=true é adequado a uma estação nem sempre ligada. Cron é aceitável em uma máquina continuamente ativa.

Restaurar

Teste periodicamente em uma instalação isolada:

  1. valide COMPLETE, SHA256SUMS e gzip -t;
  2. use a versão registrada em manifest.env;
  3. coloque o destino em manutenção e pare workers;
  4. crie backup preventivo do destino;
  5. recrie a base e importe database.sql.gz;
  6. restaure media e datasets em storage/app/public;
  7. restaure a APP_KEY correspondente e secrets necessários;
  8. corrija proprietário e permissões;
  9. execute php artisan migrate --force, php artisan optimize e php artisan locales:audit;
  10. verifique logs, login, contagens, mídias, versões de datasets e um job pequeno antes de reabrir o acesso.

Em migração MariaDB para MySQL, versões recentes do mariadb-dump podem incluir uma diretiva inicial de sandbox incompatível com o MySQL da Oracle. Remova apenas essa diretiva exata; nunca elimine cegamente a primeira linha do SQL.

Verificações operacionais

Monitore:

  • idade e tamanho de LATEST;
  • código de saída e logs do backup no servidor;
  • state/last-success no destino do pull;
  • espaço livre em ambas as máquinas;
  • verificação periódica de checksums;
  • restauração real de teste ao menos trimestralmente.

Um backup só está comprovado quando uma restauração funciona.

Última modificação September 30, 2026: Updated installation for media imports and limits (44b7330)