databases/Artigo

    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
    Dica
    pg_dump é consistente — usa transações internas e não bloqueia o banco durante a exportação. Você pode fazer backups com o PostgreSQL em produção recebendo conexões normalmente.

    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
    Dica
    Backups em formato custom (-Fc) só podem ser restaurados com pg_restore, não com psql. São menores e mais rápidos de restaurar em bancos grandes (> 1 GB).

    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
    Atenção
    --clean remove os objetos existentes antes de recriar. Use com cuidado em bancos em produção — garante um restore limpo mas destrói dados atuais.

    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/
    Dica
    Cloudflare R2 tem 10 GB gratuitos/mês e zero custo de egress — ideal para backups. Configure como provider S3-compatible no rclone usando endpoint storage.cloudflare.com.

    $ runstack deploy --plan starter

    Não quer configurar manualmente?

    Não quer configurar manualmente? Implante o PostgreSQL em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.

    Perguntas frequentes