Contexto
A API HCF roda em um container gerenciado pelo CapRover, enquanto o PostgreSQL está instalado na máquina host. Precisamos de backups automatizados diários armazenados fora do servidor, no Google Drive.
Já existe um padrão semelhante no repositório da API: script/database-sync/ — um container Debian com cron e postgresql-client-18, implantado como app separado no CapRover. O serviço de backup deve seguir a mesma abordagem.
Objetivo
Criar um novo serviço standalone em script/database-backup/ que:
- Conecte-se ao PostgreSQL na máquina host
- Execute backups agendados via cron
- Envie o backup para uma pasta específica no Google Drive
- Aplique uma política de retenção para evitar crescimento indefinido no Drive
Arquitetura proposta
- Container: Debian slim +
postgresql-client-18 + rclone + cron
- Deploy: App separado no CapRover (como o
database-sync)
- Estado: Container stateless; os backups ficam apenas no Google Drive (arquivos locais em
/tmp são temporários)
Fluxo: cron → backup.sh → pg_dump (SQL plain) → gzip → upload via rclone → Google Drive → lógica de retenção → exclusão de backups antigos
Formato do backup
| Decisão |
Escolha |
| Formato do dump |
SQL plain (pg_dump -Fp) |
| Compressão |
gzip (.sql.gz) — preferível ao zip para dumps SQL |
| Padrão do nome |
{DATABASE_NAME}_{unix_timestamp}.sql.gz |
| Exemplo |
herbario_prod_1748469600.sql.gz |
Timestamps Unix ordenam corretamente pelo nome e deixam explícito o horário do backup.
Exemplo de restore:
gunzip -c herbario_prod_<unix_ts>.sql.gz | psql -h <host> -U <user> -d <database>
Política de retenção
Após cada upload bem-sucedido, limpar arquivos antigos na pasta do Drive:
| Nível |
Regra |
Quantidade |
| Diário |
Manter os 5 backups mais recentes |
5 |
| Semanal |
Entre os restantes, manter 1 por semana ISO nas 4 semanas distintas mais recentes |
até 4 |
| Excluir |
Todo o restante |
— |
Máximo de arquivos no Drive: 9
Notas de implementação:
- Listar arquivos
*.sql.gz da pasta do Drive via rclone
- Ordenar pelo timestamp Unix extraído do nome do arquivo
- Para agrupamento semanal, converter o timestamp de volta para data e usar semana ISO (
%G-W%V)
- Excluir arquivos não mantidos com
rclone deletefile
Arquivos a criar
Todos em script/database-backup/:
| Arquivo |
Propósito |
Dockerfile |
Imagem Debian slim com pg client, rclone, cron, gzip |
entrypoint.sh |
Gerar config do rclone a partir de env vars, registrar cron, iniciar cron |
backup.sh |
Dump → compressão → upload → retenção → limpeza |
docker-compose.yml |
Testes locais / config de referência |
.env.example |
Variáveis de ambiente documentadas |
captain-definition.json |
Config de deploy no CapRover |
Seguir as convenções de script/database-sync/ (padrão do entrypoint, repasse de env vars ao cron via /etc/environment, logs em /proc/1/fd/1).
Variáveis de ambiente
| Variável |
Descrição |
Exemplo |
DATABASE_HOST |
Endereço do PostgreSQL na host (acessível pela rede do CapRover) |
10.0.10.80 |
DATABASE_PORT |
Porta do PostgreSQL |
5432 |
DATABASE_USER |
Usuário do banco |
postgres |
DATABASE_PASSWORD |
Senha do banco |
(segredo) |
DATABASE_NAME |
Nome do banco |
herbario_prod |
GDRIVE_TOKEN |
JSON do token OAuth2 do rclone |
(segredo) |
GDRIVE_FOLDER_ID |
ID da pasta de destino no Google Drive |
(da URL do Drive) |
RETENTION_DAILY |
Quantidade de backups diários a manter |
5 |
RETENTION_WEEKLY |
Quantidade de backups semanais a manter |
4 |
CRON_SCHEDULE |
Expressão cron |
0 2 * * * |
TZ |
Fuso horário |
America/Sao_Paulo |
Critérios de aceite
Checklist de testes
Fora do escopo
- Backup de arquivos/mídia enviados (
STORAGE_PATH) — apenas banco de dados
- Alertas em caso de falha no backup (pode ser uma issue de follow-up)
- Criptografia adicional dos backups além dos controles de acesso do Google Drive
Referências
- Padrão existente:
script/database-sync/ (repositório hcf-api)
Contexto
A API HCF roda em um container gerenciado pelo CapRover, enquanto o PostgreSQL está instalado na máquina host. Precisamos de backups automatizados diários armazenados fora do servidor, no Google Drive.
Já existe um padrão semelhante no repositório da API:
script/database-sync/— um container Debian com cron epostgresql-client-18, implantado como app separado no CapRover. O serviço de backup deve seguir a mesma abordagem.Objetivo
Criar um novo serviço standalone em
script/database-backup/que:Arquitetura proposta
postgresql-client-18+rclone+crondatabase-sync)/tmpsão temporários)Fluxo: cron →
backup.sh→pg_dump(SQL plain) →gzip→ upload viarclone→ Google Drive → lógica de retenção → exclusão de backups antigosFormato do backup
pg_dump -Fp)gzip(.sql.gz) — preferível ao zip para dumps SQL{DATABASE_NAME}_{unix_timestamp}.sql.gzherbario_prod_1748469600.sql.gzTimestamps Unix ordenam corretamente pelo nome e deixam explícito o horário do backup.
Exemplo de restore:
Política de retenção
Após cada upload bem-sucedido, limpar arquivos antigos na pasta do Drive:
Máximo de arquivos no Drive: 9
Notas de implementação:
*.sql.gzda pasta do Drive viarclone%G-W%V)rclone deletefileArquivos a criar
Todos em
script/database-backup/:Dockerfileentrypoint.shbackup.shdocker-compose.yml.env.examplecaptain-definition.jsonSeguir as convenções de
script/database-sync/(padrão do entrypoint, repasse de env vars ao cron via/etc/environment, logs em/proc/1/fd/1).Variáveis de ambiente
DATABASE_HOST10.0.10.80DATABASE_PORT5432DATABASE_USERpostgresDATABASE_PASSWORDDATABASE_NAMEherbario_prodGDRIVE_TOKENGDRIVE_FOLDER_IDRETENTION_DAILY5RETENTION_WEEKLY4CRON_SCHEDULE0 2 * * *TZAmerica/Sao_PauloCritérios de aceite
script/database-backup/seguindo o padrão do containerdatabase-sync{database}_{unix_timestamp}.sql.gz.env.exampledocumenta todas as variáveis necessáriaspsql)Checklist de testes
docker compose buildemscript/database-backup/Fora do escopo
STORAGE_PATH) — apenas banco de dadosReferências
script/database-sync/(repositório hcf-api)