Backup e restore do PostgreSQL com Docker

Fazer backup do PostgreSQL no Docker requer apenas o pg_dump rodando dentro do container, o banco não precisa ser parado. Para restore, use psql ou pg_restore dependendo do formato. Automatize com cron e envie o backup para armazenamento externo para não depender do disco da VPS.

Backup com pg_dump (formato SQL)

pg_dump exporta o banco para um arquivo SQL que pode ser importado em qualquer PostgreSQL. É o formato mais portável e legível:

bash
# Backup de um banco específico (formato SQL)
docker compose exec postgres pg_dump \
  -U postgres \
  -d nome_do_banco \
  > backup-$(date +%Y%m%d-%H%M%S).sql

# Backup comprimido (reduz tamanho em 5-10x)
docker compose exec postgres pg_dump \
  -U postgres \
  -d nome_do_banco \
  | gzip > backup-$(date +%Y%m%d-%H%M%S).sql.gz

# Backup de todos os bancos (pg_dumpall)
docker compose exec postgres pg_dumpall \
  -U postgres \
  > backup-all-$(date +%Y%m%d).sql

Backup em formato custom (recomendado para produção)

O formato custom (-Fc) é comprimido, permite restauração paralela e seletiva por tabela, mais eficiente que SQL puro para bancos grandes:

bash
# Backup em formato custom (binário comprimido)
docker compose exec postgres pg_dump \
  -U postgres \
  -d nome_do_banco \
  -Fc \
  -f /tmp/backup.dump

# Copiar o arquivo para fora do container
docker cp nome_do_container_postgres:/tmp/backup.dump ./backup-$(date +%Y%m%d).dump

# Verificar integridade do backup
pg_restore --list ./backup-$(date +%Y%m%d).dump | head -20

Restaurar o banco

O processo de restore depende do formato do backup:

bash
# Restaurar arquivo SQL (formato texto)
cat backup.sql | docker compose exec -T postgres psql -U postgres -d nome_do_banco

# Restaurar arquivo SQL comprimido
gunzip -c backup.sql.gz | docker compose exec -T postgres psql -U postgres -d nome_do_banco

# Restaurar formato custom (pg_restore)
docker cp backup.dump nome_do_container_postgres:/tmp/backup.dump
docker compose exec postgres pg_restore \
  -U postgres \
  -d nome_do_banco \
  --clean \
  --if-exists \
  /tmp/backup.dump

# Criar banco novo e restaurar do zero
docker compose exec postgres psql -U postgres \
  -c "CREATE DATABASE nome_do_banco_novo OWNER postgres;"
docker compose exec postgres pg_restore \
  -U postgres -d nome_do_banco_novo /tmp/backup.dump

Automatizar backup com cron

Configure backups automáticos com rotação (mantém os últimos 7 dias):

bash
# Script de backup — salvar em /opt/backup-postgres.sh
cat > /opt/backup-postgres.sh << 'SCRIPT'
#!/bin/bash
BACKUP_DIR="/opt/backups/postgres"
CONTAINER="nome_do_projeto-postgres-1"
DB="nome_do_banco"
DATE=$(date +%Y%m%d-%H%M%S)

mkdir -p "$BACKUP_DIR"

docker exec "$CONTAINER" pg_dump -U postgres -d "$DB" -Fc \
  > "$BACKUP_DIR/backup-$DATE.dump"

# Manter apenas os últimos 7 backups
ls -t "$BACKUP_DIR"/backup-*.dump | tail -n +8 | xargs -r rm

echo "Backup $DATE concluído. Tamanho: $(du -sh $BACKUP_DIR/backup-$DATE.dump | cut -f1)"
SCRIPT

chmod +x /opt/backup-postgres.sh

# Adicionar ao crontab (todo dia às 2h da manhã)
echo "0 2 * * * /opt/backup-postgres.sh >> /var/log/backup-postgres.log 2>&1" | crontab -

Enviar backup para armazenamento externo

Backups locais na VPS são perdidos junto com a VPS em caso de falha. Envie para S3, R2 ou outro armazenamento:

bash
# Instalar rclone (gerenciador de armazenamento em nuvem)
curl https://rclone.org/install.sh | sudo bash

# Configurar bucket S3/R2/B2 (interativo)
rclone config

# Adicionar upload ao script de backup
# Após a linha do pg_dump:
rclone copy "$BACKUP_DIR/backup-$DATE.dump" remote:nome-do-bucket/postgres/

# Testar o envio
rclone ls remote:nome-do-bucket/postgres/

Não quer configurar manualmente?

Implante o PostgreSQL em menos de 5 minutos com a Runstack. Infraestrutura da OPEN Datacenter, com servidores em São Paulo.

Perguntas frequentes

pg_dump exporta um banco específico (sem roles nem tablespaces). pg_dumpall exporta todos os bancos + roles + configurações globais, útil para migração completa de servidor. Para backups rotineiros de produção, pg_dump por banco é mais granular e prático.

pg_dump usa MVCC do PostgreSQL, tira um snapshot consistente sem bloquear escritas. Conexões continuam normalmente durante o backup. O único impacto é CPU e I/O adicionais durante a exportação, em bancos grandes, considere fazer o backup em horário de baixo tráfego.

pg_dump é mais confiável: exporta apenas os dados, é portável entre versões do PostgreSQL e pode ser restaurado seletivamente por tabela. Backup do volume Docker captura arquivos internos do banco, pode ficar inconsistente se feito com o banco em uso. Use pg_dump para backups regulares e backup de volume como segurança extra antes de atualizações.

Para formato SQL: pg_restore --list backup.dump (lista objetos sem restaurar). Para formato texto: head -20 backup.sql deve mostrar os headers do PostgreSQL. O teste definitivo é restaurar em um banco temporário: docker compose exec postgres createdb -U postgres teste_restore && pg_restore -U postgres -d teste_restore backup.dump.

Formato SQL comprimido com gzip: 5–15% do tamanho original do banco. Formato custom (-Fc): 10–20% do original. Um banco de 10 GB vira ~500 MB–2 GB em backup. Índices não são essenciais no backup, pg_restore os recria a partir dos dados.