databases/Artigo

    Migrar SQLite para PostgreSQL

    SQLite é o banco padrão de muitas ferramentas self-hosted (n8n, Flowise, NocoDB) por ser simples de configurar, mas não escala bem com múltiplos usuários simultâneos. A migração para PostgreSQL é necessária quando o app começa a travar, o banco de dados fica corrupto após crash, ou você precisa de backup consistente. O processo preserva todos os dados e não requer reinstalação do app.

    Quando migrar de SQLite para PostgreSQL

    SQLite tem limitações claras que indicam quando a migração é necessária:

    bash
    # Sinais de que o SQLite está sendo o gargalo:
    
    # 1. Erros "database is locked" nos logs
    docker compose logs nome_do_app | grep -i "locked\|busy\|database"
    
    # 2. Múltiplos usuários ou workers acessando simultaneamente
    # SQLite suporta apenas um escritor por vez
    
    # 3. Banco > 1 GB (performance degrada)
    ls -lh caminho/para/o/banco.sqlite
    
    # 4. Necessidade de backup consistente (pg_dump vs cp do arquivo)
    
    # 5. App rodando com múltiplos réplicas ou workers
    # SQLite em bind mount compartilhado entre containers = corrupção certa
    
    # Verificar tamanho e último acesso ao banco SQLite
    docker compose exec nome_app find / -name "*.sqlite" -o -name "*.db" 2>/dev/null
    Dica
    SQLite em produção é suficiente para apps com < 100 requisições/segundo e usuário único. A migração para PostgreSQL é um investimento que vale para apps com crescimento previsto.

    Migrar n8n de SQLite para PostgreSQL

    n8n armazena workflows, credenciais e execuções no banco. A migração oficial usa variáveis de ambiente — não existe comando de migração automática, mas os dados não precisam ser migrados (workflows são re-importados):

    yaml
    # Opção 1: Exportar workflows e recriar do zero (mais simples)
    # 1. Exportar todos os workflows via interface n8n
    #    Settings → Import/Export → Export all workflows
    
    # 2. Adicionar PostgreSQL ao docker-compose.yml
    services:
      postgres:
        image: postgres:16-alpine
        environment:
          POSTGRES_DB: n8n
          POSTGRES_USER: n8n
          POSTGRES_PASSWORD: ${DB_PASSWORD}
        volumes:
          - pg_data:/var/lib/postgresql/data
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -U n8n"]
          interval: 5s
          retries: 5
    
      n8n:
        environment:
          DB_TYPE: postgresdb
          DB_POSTGRESDB_HOST: postgres
          DB_POSTGRESDB_DATABASE: n8n
          DB_POSTGRESDB_USER: n8n
          DB_POSTGRESDB_PASSWORD: ${DB_PASSWORD}
        depends_on:
          postgres:
            condition: service_healthy
    
    # 3. Recriar containers (banco vazio, migração automática na 1ª inicialização)
    docker compose down
    docker compose up -d
    
    # 4. Importar workflows exportados
    #    Settings → Import/Export → Import from file
    Dica
    Credenciais criptografadas do n8n não podem ser exportadas/importadas via UI por segurança. Será necessário reconfigurar as credenciais (chaves de API, senhas) após a migração.

    Migrar banco SQLite genérico com pgloader

    pgloader converte automaticamente tipos de dados e migra os dados de SQLite para PostgreSQL:

    bash
    # Copiar o arquivo SQLite do container para o host
    docker cp nome_do_container:/caminho/para/banco.sqlite ./banco.sqlite
    
    # Criar banco de destino no PostgreSQL
    docker compose exec postgres psql -U postgres \
      -c "CREATE DATABASE nome_do_banco OWNER postgres;"
    
    # Rodar pgloader
    docker run --rm \
      --network nome_da_rede_docker \
      -v $(pwd)/banco.sqlite:/tmp/banco.sqlite \
      dimitri/pgloader:latest pgloader \
      /tmp/banco.sqlite \
      postgresql://postgres:senha@postgres/nome_do_banco
    
    # Verificar contagem de registros após migração
    docker compose exec postgres psql -U postgres -d nome_do_banco \
      -c "SELECT tablename, n_live_tup FROM pg_stat_user_tables ORDER BY n_live_tup DESC;"
    Atenção
    pgloader converte os tipos de dados automaticamente, mas SQLite é typeless — uma coluna "INTEGER" pode ter strings. Verifique as tabelas após a migração e ajuste constraints conforme necessário.

    Migrar Flowise de SQLite para PostgreSQL

    Flowise suporta PostgreSQL via variável de ambiente — a migração é transparente após configurar o banco:

    bash
    # No docker-compose.yml do Flowise, adicionar/alterar:
    services:
      flowise:
        environment:
          DATABASE_TYPE: postgres
          DATABASE_HOST: postgres
          DATABASE_PORT: 5432
          DATABASE_NAME: flowise
          DATABASE_USER: flowise
          DATABASE_PASSWORD: ${DB_PASSWORD}
    
    # Primeiro, criar o banco no PostgreSQL:
    docker compose exec postgres psql -U postgres << 'EOF'
    CREATE USER flowise WITH PASSWORD 'sua_senha';
    CREATE DATABASE flowise OWNER flowise;
    GRANT ALL PRIVILEGES ON DATABASE flowise TO flowise;
    EOF
    
    # Recriar o container do Flowise
    docker compose down flowise
    docker compose up -d flowise
    
    # Na primeira inicialização, Flowise cria o schema automaticamente
    docker compose logs flowise --tail=20

    Verificar a migração e rollback

    Valide os dados antes de remover o SQLite e saiba como fazer rollback se necessário:

    bash
    # Comparar contagem de registros SQLite vs PostgreSQL
    # SQLite (via sqlite3 local ou dentro do container):
    docker compose exec nome_app sqlite3 /caminho/banco.sqlite \
      "SELECT name, COUNT(*) FROM sqlite_master WHERE type='table' GROUP BY name;"
    
    # PostgreSQL:
    docker compose exec postgres psql -U postgres -d nome_do_banco \
      -c "SELECT tablename, n_live_tup FROM pg_stat_user_tables;"
    
    # Manter backup do SQLite por 30 dias antes de deletar
    cp banco.sqlite banco-sqlite-backup-$(date +%Y%m%d).sqlite
    
    # Rollback: reverter variáveis de ambiente e apontar para SQLite novamente
    # Dados criados após a migração serão perdidos no rollback
    Dica
    Nunca delete o arquivo SQLite imediatamente após a migração. Mantenha-o por pelo menos uma semana em produção para ter opção de rollback se algo inesperado acontecer.

    $ 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