[{"data":1,"prerenderedAt":1163},["ShallowReactive",2],{"blog-pt-supabase-backup-github-action":3,"blog-index-pt":817},{"id":4,"title":5,"body":6,"category":770,"cover":771,"coverAlt":772,"description":773,"draft":774,"extension":775,"faq":776,"image":794,"keywords":795,"meta":804,"navigation":805,"ogTitle":806,"path":807,"published":808,"seo":809,"stem":810,"tldr":811,"updated":815,"__hash__":816},"blog_pt\u002Fblog\u002Fsupabase-backup-github-action.md","Backup grátis do Supabase com uma GitHub Action, e a pegadinha",{"type":7,"value":8,"toc":754},"minimark",[9,13,21,24,29,40,49,57,60,64,72,82,85,139,146,153,157,160,177,191,197,200,203,207,216,225,233,242,245,249,252,255,335,338,341,346,349,357,360,364,377,398,404,407,410,416,422,459,465,468,472,475,478,515,518,522,530,548,552,555,571,579,584,592,601,607,610,614,617,645,649,654,697,710,714,746],[10,11,12],"p",{},"Seu projeto no Supabase está no plano gratuito, então nada está sendo copiado\npara lugar nenhum, ou está no Pro e toda cópia que ele faz mora dentro da conta\nque você tem medo de perder. Num tópico justamente sobre isso, alguém disse que a\nresposta é uma GitHub Action de backup do Supabase: um arquivo pequeno num\nrepositório que exporta seu banco toda noite e não custa nada.",[10,14,15,16,20],{},"O conselho estava certo. O próprio Supabase publica o workflow, e para muitos\napps é o que vale montar esta semana. Esta é a parte que esses tópicos deixam de\nfora: ",[17,18,19],"strong",{},"não custa dinheiro e ainda assim tem um preço."," Cada execução baixa seu\nbanco de dados inteiro, e o Supabase mede esse download.",[10,22,23],{},"Pense nisso como a franquia de dados do seu plano de celular. Seu plano vem com\numa cota mensal, tudo o que seu app faz puxa dela, e um backup é um download\ngrande no mesmo plano. No plano gratuito, uma cópia noturna de um banco perto do\nlimite de tamanho consome a cota do mês inteiro em uns dez dias. Isso, e uma\nconnection string que o GitHub não alcança, são as duas coisas entre você e um\nbackup que funciona, e nenhuma delas está na página do Supabase.",[25,26,28],"h2",{"id":27},"dá-para-fazer-backup-do-supabase-de-graça-com-uma-github-action","Dá para fazer backup do Supabase de graça com uma GitHub Action?",[10,30,31,32,39],{},"Dá, e o Supabase documenta como. A página dele sobre\n",[33,34,38],"a",{"href":35,"rel":36},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fdeployment\u002Fci\u002Fbackups",[37],"nofollow","backups automáticos com GitHub Actions","\ntraz um workflow que instala a CLI do Supabase, exporta seus roles, seu schema e\nseus dados em três arquivos e faz commit deles de volta no repositório num\nhorário fixo.",[10,41,42,43,48],{},"O GitHub também não cobra por isso, dentro de certos limites. Um repositório\nprivado no GitHub Free ganha\n",[33,44,47],{"href":45,"rel":46},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Fbilling\u002Fconcepts\u002Fproduct-billing\u002Fgithub-actions",[37],"2.000 minutos de Actions por mês",",\ne um dump noturno de um banco pequeno usa uma parte pequena disso.",[10,50,51,52,56],{},"O que você ganha é uma cópia que sai do Supabase toda noite e vai parar nos\nservidores de outra empresa. É exatamente isso que os backups do próprio\nSupabase não conseguem te dar, porque as cópias diárias de um plano pago\n",[33,53,55],{"href":54},"\u002Fblog\u002Fdownload-your-supabase-backup","ficam dentro da conta que elas protegem",".",[10,58,59],{},"É a resposta certa quando três coisas são verdade. Seu app já mora num\nrepositório do GitHub, o que acontece se você ligou a sincronização com o GitHub\nno Lovable ou num builder parecido. Editar um arquivo YAML não te assusta. E seu\nbanco é pequeno perto da cota de egress do seu plano. As duas primeiras você já\nsabe. A terceira é conta, e tem uma seção própria mais abaixo.",[25,61,63],{"id":62},"o-workflow-com-o-horário-e-o-secret","O workflow, com o horário e o secret",[10,65,66,67,71],{},"Salve isto como ",[68,69,70],"code",{},".github\u002Fworkflows\u002Fsupabase-backup.yml"," num repositório privado\nque não tenha mais nada:",[73,74,80],"pre",{"className":75,"code":77,"language":78,"meta":79},[76],"language-yaml","name: supabase-backup\n\non:\n  schedule:\n    - cron: '17 3 * * *' # todo dia às 03:17 UTC\n  workflow_dispatch:\n\njobs:\n  backup:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n    env:\n      SUPABASE_DB_URL: ${{ secrets.SUPABASE_DB_URL }}\n    steps:\n      - uses: actions\u002Fcheckout@v7\n      - uses: supabase\u002Fsetup-cli@v3\n        with:\n          version: latest\n      - name: Back up roles\n        run: supabase db dump --db-url \"$SUPABASE_DB_URL\" -f roles.sql --role-only\n      - name: Back up schema\n        run: supabase db dump --db-url \"$SUPABASE_DB_URL\" -f schema.sql\n      - name: Back up data\n        run: >\n          supabase db dump --db-url \"$SUPABASE_DB_URL\" -f data.sql --use-copy --data-only\n          -x \"storage.buckets_vectors\" -x \"storage.vector_indexes\"\n      - uses: stefanzweifel\u002Fgit-auto-commit-action@v7\n        with:\n          commit_message: Supabase backup\n","yaml","",[68,81,77],{"__ignoreMap":79},[10,83,84],{},"É o workflow do Supabase com três mudanças.",[86,87,88,99,123],"ul",{},[89,90,91,94,95,98],"li",{},[17,92,93],{},"Ele roda no horário e quando você aperta o botão, e em nenhum outro\nmomento."," A versão do Supabase também roda a cada push e a cada pull request\npara a ",[68,96,97],{},"main",". Cada execução é um download completo do seu banco, então num\nrepositório que também guarda o seu app, cada mudança que você publicasse\ngastaria a cota de um backup.",[89,100,101,104,105,110,111,114,115,118,119,122],{},[17,102,103],{},"Ele roda às 03:17, fora da hora cheia."," O GitHub diz que execuções\nagendadas\n",[33,106,109],{"href":107,"rel":108},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Factions\u002Freference\u002Fworkflows-and-actions\u002Fevents-that-trigger-workflows#schedule",[37],"podem atrasar no início de cada hora",",\ne que com carga suficiente alguns jobs na fila são descartados. O exemplo do\nSupabase usa ",[68,112,113],{},"0 0 * * *",", que cai na hora cheia. Os horários são em UTC, a\nmenos que você adicione um ",[68,116,117],{},"timezone",", e qualquer minuto diferente de ",[68,120,121],{},"0","\nserve.",[89,124,125,134,135,138],{},[17,126,127,128,133],{},"A linha dos dados segue o\n",[33,129,132],{"href":130,"rel":131},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fplatform\u002Fmigrating-within-supabase\u002Fbackup-restore",[37],"guia atual de backup e restauração","\ndo Supabase",", que acrescenta duas exclusões ",[68,136,137],{},"-x"," que a página do workflow não\ntem. Assim os arquivos que você guarda são aqueles para os quais as instruções\nde restauração do Supabase foram escritas.",[10,140,141,142,145],{},"Depois, o secret. No repositório, abra Settings, depois Secrets and variables,\ndepois Actions, e adicione um secret de repositório chamado ",[68,143,144],{},"SUPABASE_DB_URL",". O\nque vai dentro dele decide se tudo isso funciona, então ele ganha a próxima\nseção só para ele.",[10,147,148,149,152],{},"Depois de salvar, rode o workflow na mão pela aba Actions, para que a primeira\nexecução aconteça enquanto você olha. ",[68,150,151],{},"workflow_dispatch"," é a linha que te dá o\nbotão Run workflow.",[25,154,156],{"id":155},"qual-connection-string-vai-no-secret","Qual connection string vai no secret?",[10,158,159],{},"A string do Session pooler, pelo botão Connect no topo do seu projeto no\nSupabase. Use essa mesmo que a página do workflow do Supabase mostre a conexão\ndireta no exemplo.",[10,161,162,163,166,167,170,171,176],{},"O motivo é o IPv6, o tipo mais novo de endereço de internet. A conexão direta do\nSupabase, o host que começa com ",[68,164,165],{},"db."," e termina em ",[68,168,169],{},"supabase.co",",\n",[33,172,175],{"href":173,"rel":174},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fplatform\u002Fipv4-address",[37],"usa IPv6 por padrão",",\ne a mesma página lista o GitHub Actions entre os serviços que só aceitam IPv4. O\nrunner recebe um endereço para o qual não tem caminho, e o primeiro dump falha\nantes de escrever um único byte. O erro diz que o nome do host não pôde ser\ntraduzido, ou que a rede está inacessível, muitas vezes com um endereço longo\ncheio de dois-pontos ao lado. Esse endereço é o IPv6. Parece uma senha errada ou\num banco fora do ar, e a causa real é uma rede em que o runner não está.",[10,178,179,180,183,184,187,188,56],{},"O guia de backup e restauração do Supabase diz para usar por padrão a string do\nSession pooler, e a direta só se a sua rede suporta IPv6 ou se você paga o\nadd-on de IPv4. Você reconhece a string do pooler por três coisas: o nome de\nusuário é ",[68,181,182],{},"postgres."," seguido da referência do seu projeto, o host termina em\n",[68,185,186],{},"pooler.supabase.com"," e a porta é ",[68,189,190],{},"5432",[192,193],"diagram",{"alt":194,"caption":195,"src":196},"Um runner do GitHub à esquerda com dois caminhos saindo dele. O de cima leva o host direto db.[ref].supabase.co, está marcado IPv6 e para num muro com um X antes do banco de dados. O de baixo leva o host pooler.supabase.com, está marcado IPv4 e chega ao banco com um visto.","O runner não tem caminho até o endereço IPv6 da conexão direta. O Session pooler responde por IPv4 e chega ao mesmo banco.","\u002Fblog\u002Fsupabase-backup-github-action\u002Fwhich-string-reaches-the-runner-1600x620.png",[10,198,199],{},"A senha dentro dela é a senha do seu banco de dados, a definida quando o projeto\nfoi criado, e não uma chave de API. Se ninguém anotou, o Supabase deixa você\nredefini-la em Database Settings; qualquer outra coisa que se conecte com a\nantiga para de funcionar até você passar a nova.",[10,201,202],{},"Essa string consegue ler e alterar cada linha do seu banco. Ela vive no secret e\nem nenhum outro lugar: nunca no arquivo do workflow, nunca numa mensagem de\ncommit e nunca colada num assistente de IA junto com o erro que você ia\nperguntar.",[25,204,206],{"id":205},"um-backup-do-supabase-conta-no-meu-egress","Um backup do Supabase conta no meu egress?",[10,208,209,210,215],{},"Conta, inteiro. O Supabase conta como\n",[33,211,214],{"href":212,"rel":213},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fplatform\u002Fmanage-your-usage\u002Fegress",[37],"egress",",\nou seja, tráfego de saída, os dados que qualquer um dos seus serviços manda para\nfora, e um dump pelo pooler entra como Shared Pooler Egress na mesma cota do seu\ntráfego de API, dos seus downloads de arquivos e de tudo o que o seu app entrega.",[10,217,218,219,224],{},"Voltando ao plano de celular. A cota zera a cada mês de cobrança, todo serviço\nque o seu app usa puxa dela, e um backup é mais um download grande. E é um plano\nfamília: o Supabase aplica a cota à\n",[33,220,223],{"href":221,"rel":222},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fplatform\u002Fbilling-on-supabase",[37],"sua organização inteira",",\nentão todos os projetos dela dividem a mesma cota.",[10,226,227,228,232],{},"Em 26 de setembro de 2026, a página de preços do Supabase dava ao plano gratuito\n5 GB de egress por mês e um limite de 500 MB para o banco de cada projeto, e ao\nplano Pro 250 GB de egress. O plano gratuito tem mais 5 GB de cached egress, que\ncobre arquivos servidos pela CDN do Supabase, e um backup nunca toca nele. Os outros limites do plano gratuito, e ",[33,229,231],{"href":230},"\u002Fblog\u002Fsupabase-free-plan-limits","o que cada um faz quando você passa dele",", têm um artigo só deles.",[10,234,235,236,241],{},"Estourar a cota no plano gratuito não gera uma fatura. O Supabase\n",[33,237,240],{"href":238,"rel":239},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fplatform\u002Fbilling-faq",[37],"avisa você e dá um período de carência",",\ne se você continuar acima dela, ele restringe todos os projetos da organização.\nSegundo o Supabase, isso pode significar requisições de API respondidas com erro\n402, um banco colocado em modo somente leitura ou projetos pausados. Para um app\ncom clientes, é uma queda que o seu backup começou.",[10,243,244],{},"Isso vale para qualquer backup que sai do Supabase, inclusive o que nós\nvendemos. Uma cópia guardada fora da conta precisa ser baixada para chegar lá.",[25,246,248],{"id":247},"com-que-frequência-o-backup-deve-rodar","Com que frequência o backup deve rodar?",[10,250,251],{},"Com a frequência que a sua cota consegue pagar, e isso se resume a uma única\nmultiplicação: o tamanho do seu banco vezes as execuções do mês.",[10,253,254],{},"O Supabase mostra o tamanho do seu banco no relatório Database, dentro de\nObservability no seu projeto. Um dump não tem exatamente esse tamanho. Ele deixa\nde fora os índices, que são reconstruídos a partir das definições, e escreve\ncada valor como texto. Chega perto o bastante para planejar, e é o número que\nvocê consegue consultar.",[256,257,258,277],"table",{},[259,260,261],"thead",{},[262,263,264,268,271,274],"tr",{},[265,266,267],"th",{},"Tamanho do banco",[265,269,270],{},"Diário (30 execuções)",[265,272,273],{},"Duas vezes por semana",[265,275,276],{},"Semanal",[278,279,280,295,308,322],"tbody",{},[262,281,282,286,289,292],{},[283,284,285],"td",{},"50 MB",[283,287,288],{},"1,5 GB",[283,290,291],{},"0,4 GB",[283,293,294],{},"0,2 GB",[262,296,297,300,303,306],{},[283,298,299],{},"100 MB",[283,301,302],{},"3 GB",[283,304,305],{},"0,9 GB",[283,307,291],{},[262,309,310,313,316,319],{},[283,311,312],{},"250 MB",[283,314,315],{},"7,5 GB",[283,317,318],{},"2,2 GB",[283,320,321],{},"1,1 GB",[262,323,324,327,330,333],{},[283,325,326],{},"500 MB",[283,328,329],{},"15 GB",[283,331,332],{},"4,3 GB",[283,334,318],{},[10,336,337],{},"Um mês tem cerca de 4,3 semanas, e é daí que saem as duas últimas colunas.",[10,339,340],{},"No plano gratuito, os dois números diários de baixo gastam mais do que a cota\ndo mês inteiro antes de o seu app responder uma única requisição. Um horário\ndiário consome os 5 GB inteiros por volta de 160 MB, e o tráfego do seu próprio\napp sai da mesma cota, então veja o egress do mês passado na página Usage da sua\norganização antes de escolher. O semanal cabe em qualquer tamanho que o plano\ngratuito permite.",[192,342],{"alt":343,"caption":344,"src":345},"Um banco de dados com um símbolo de repetição ao lado de duas colunas de blocos: trinta cópias num mês à esquerda, quatro à direita. Uma linha tracejada marca a cota mensal. A coluna da esquerda passa dela a um terço da altura, e os blocos acima da linha são âmbar. A da direita fica bem abaixo, em turquesa.","Um banco no limite de 500 MB do plano gratuito, com backup diário e semanal. A linha tracejada são os 5 GB de egress do plano gratuito no mês.","\u002Fblog\u002Fsupabase-backup-github-action\u002Fthirty-copies-four-copies-1600x680.png",[10,347,348],{},"A linha do cron é a única coisa que você muda:",[73,350,355],{"className":351,"code":353,"language":354},[352],"language-text","17 3 * * *      todo dia às 03:17 UTC\n17 3 * * 1,4    segundas e quintas\n17 3 * * 0      domingos\n","text",[68,356,353],{"__ignoreMap":79},[10,358,359],{},"No Pro a conta quase deixa de importar. 250 GB por mês pagam um dump diário de\num projeto de até uns 8 GB, que é o espaço em disco que o plano Pro inclui por\nprojeto.",[25,361,363],{"id":362},"por-que-meu-workflow-falha-com-um-erro-de-versão-do-pg_dump","Por que meu workflow falha com um erro de versão do pg_dump?",[10,365,366,367,370,371,373,374,376],{},"Porque o ",[68,368,369],{},"pg_dump"," que ele rodou é mais antigo que o seu banco. Isso só acontece\ncom um workflow que chama o ",[68,372,369],{}," diretamente, e não pela CLI do Supabase. A\nCLI traz o próprio ",[68,375,369],{},", e esse é um dos motivos de o workflow acima usá-la.",[10,378,379,380,383,384,389,390,392,397],{},"O runner ",[68,381,382],{},"ubuntu-latest"," do GitHub vem com o\n",[33,385,388],{"href":386,"rel":387},"https:\u002F\u002Fgithub.com\u002Factions\u002Frunner-images\u002Fblob\u002Fmain\u002Fimages\u002Fubuntu\u002FUbuntu2404-Readme.md",[37],"PostgreSQL 16 instalado",".\nProjetos do Supabase podem rodar em Postgres 17, e o Postgres documenta que o\n",[68,391,369],{},[33,393,396],{"href":394,"rel":395},"https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002Fcurrent\u002Fapp-pgdump.html",[37],"não exporta de um servidor com versão principal mais nova que a dele",",\ne prefere recusar a arriscar um arquivo defeituoso. A execução para com:",[73,399,402],{"className":400,"code":401,"language":354},[352],"pg_dump: error: aborting because of server version mismatch\npg_dump: detail: server version: 17.…; pg_dump version: 16.…\n",[68,403,401],{"__ignoreMap":79},[10,405,406],{},"A versão do seu projeto fica em Project Settings, depois General, se quiser\nconfirmar. Não há nada de errado com as suas credenciais.",[10,408,409],{},"A correção tem dois passos. Adicione o repositório de pacotes do próprio\nPostgreSQL para que o runner consiga instalar o cliente da versão 17, e depois\nchame esse cliente pelo caminho completo:",[73,411,414],{"className":412,"code":413,"language":78,"meta":79},[76],"- name: Install the Postgres 17 client\n  run: |\n    sudo apt-get install -y postgresql-common\n    sudo \u002Fusr\u002Fshare\u002Fpostgresql-common\u002Fpgdg\u002Fapt.postgresql.org.sh -y\n    sudo apt-get install -y postgresql-client-17\n- name: Back up\n  run: \u002Fusr\u002Flib\u002Fpostgresql\u002F17\u002Fbin\u002Fpg_dump \"$SUPABASE_DB_URL\" …\n",[68,415,413],{"__ignoreMap":79},[10,417,418,419,421],{},"Mantenha depois da connection string os argumentos que você já tinha. O caminho\ncompleto importa: no Ubuntu, o ",[68,420,369],{}," puro é um wrapper que escolhe uma\nversão por você, e o runner já tem uma instalação do PostgreSQL 16 para ele\nescolher.",[10,423,424,425,427,428,431,432,440,441,444,445,448,449,451,452,455,456,458],{},"O ",[68,426,369],{}," da CLI também tem versão, e ela não vem do seu projeto. Sem um\n",[68,429,430],{},"supabase\u002Fconfig.toml"," ao lado do workflow, que é o caso num repositório que não\nguarda mais nada, a CLI\n",[33,433,436,437,439],{"href":434,"rel":435},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fcli\u002Fblob\u002F66ccc6f63a9a26b29c368698994a0843d23b80be\u002Fapps\u002Fcli\u002Fsrc\u002Fcommand-internal\u002Fdb-config.toml-read.ts#L176",[37],"usa o ",[68,438,369],{}," 17",".\nNum projeto que ainda roda Postgres 15, o ",[68,442,443],{},"data.sql"," que ela escreve passa a ter\n",[68,446,447],{},"SET transaction_timeout = 0",", uma configuração que o Postgres 15 não tem, e a\ncarga para nessa linha em qualquer banco Postgres 15, inclusive o projeto de\nonde o arquivo veio. Reproduzimos isso em 4 de outubro de 2026 com o ",[68,450,369],{},"\n17.11 e o Postgres 15.19. Se o seu projeto está no 15, acrescente uma linha ao\nbloco ",[68,453,454],{},"env"," do job para que a CLI use o ",[68,457,369],{}," certo:",[73,460,463],{"className":461,"code":462,"language":78,"meta":79},[76],"env:\n  SUPABASE_DB_URL: ${{ secrets.SUPABASE_DB_URL }}\n  SUPABASE_DB_MAJOR_VERSION: '15'\n",[68,464,462],{"__ignoreMap":79},[10,466,467],{},"O backup em si termina sem erro nos dois casos, então sem essa linha a diferença\nsó aparece no dia em que você carrega o arquivo.",[25,469,471],{"id":470},"posso-fazer-commit-do-backup-no-meu-repositório","Posso fazer commit do backup no meu repositório?",[10,473,474],{},"Num privado, pode. É isso que o workflow do Supabase faz, e a página dele diz\nduas vezes para nunca fazer backup dos seus dados num repositório público.",[10,476,477],{},"Três coisas sobre um repositório como casa de um banco de dados, nenhuma delas\nnaquela página:",[86,479,480,494,500],{},[89,481,482,485,486,488,489,493],{},[17,483,484],{},"Quem consegue ler o repositório consegue ler os seus usuários."," O\n",[68,487,443],{}," guarda cada linha: e-mails, nomes, o que as suas tabelas\nguardarem, e ",[33,490,492],{"href":491},"\u002Fblog\u002Fsupabase-backup-auth-users","as suas contas também",". Por\nisso o workflow ganha um repositório só dele, sem mais ninguém, e não o\nrepositório do código do seu app, que o seu builder talvez sincronize e para\no qual algum dia você talvez convide um freelancer.",[89,495,496,499],{},[17,497,498],{},"A cópia de cada noite fica no histórico."," O Git guarda cada versão de cada\narquivo. Quando alguém da sua clientela pede para apagar a própria conta, a\nlinha dessa pessoa continua em cada commit anterior daquele repositório até\nvocê reescrever o histórico dele.",[89,501,502,505,506,511,512,514],{},[17,503,504],{},"Para de funcionar em 100 MiB."," O GitHub avisa acima de 50 MiB e\n",[33,507,510],{"href":508,"rel":509},"https:\u002F\u002Fdocs.github.com\u002Fen\u002Frepositories\u002Fworking-with-files\u002Fmanaging-large-files\u002Fabout-large-files-on-github",[37],"bloqueia arquivos acima de 100 MiB",",\ne a mesma página diz que o Git não foi feito para lidar com arquivos SQL\ngrandes. Na noite em que o ",[68,513,443],{}," passa desse limite, o passo de commit\nfalha, e toda execução depois disso falha do mesmo jeito.",[10,516,517],{},"Quando você chegar perto, o mesmo workflow pode enviar os três arquivos para um\nbucket de armazenamento seu em vez de fazer commit deles. Ou é o ponto em que\nfazer isso você mesmo deixou de ser barato, que é onde começa a última seção.",[25,519,521],{"id":520},"o-que-o-workflow-não-copia","O que o workflow não copia?",[10,523,524,525,529],{},"Os seus arquivos enviados. O Supabase Storage guarda cada arquivo fora do banco\ne uma linha que o descreve dentro, então o dump leva a linha e não a imagem.\n",[33,526,528],{"href":527},"\u002Fblog\u002Fsupabase-storage-backup","Fazer backup do Storage"," é um trabalho à parte,\nem qualquer caminho que você escolha.",[10,531,532,533,536,537,540,541,543,544,547],{},"Os seus usuários estão nele. O dump de dados percorre o schema ",[68,534,535],{},"auth",", onde\nmoram as suas contas, e procurar ",[68,538,539],{},"auth.users"," no ",[68,542,443],{}," mostra essas contas.\nO projeto em volta do banco não está: Edge Functions, configurações dos\nprovedores de login, chaves de API e secrets são configuração e não dados, e\n",[33,545,546],{"href":54},"a lista do que nenhuma das duas cópias guarda","\né a que vale ler antes de precisar dela.",[25,549,551],{"id":550},"uma-execução-verde-quer-dizer-que-o-backup-funcionou","Uma execução verde quer dizer que o backup funcionou?",[10,553,554],{},"Quer dizer que o job terminou sem erro, o que é uma afirmação menor. Três\nresultados bem diferentes terminam com o mesmo visto verde:",[556,557,558,561,564],"ol",{},[89,559,560],{},"Um bom dump do projeto certo.",[89,562,563],{},"Um dump do projeto errado, porque o secret tem a string de uma cópia de\nstaging.",[89,565,566,567,570],{},"Um dump sem nenhuma linha, porque alguém editou a linha dos dados e o\n",[68,568,569],{},"--data-only"," sumiu, o que a transforma de novo no dump do schema.",[10,572,573,574,578],{},"Um resultado não deixa marca nenhuma. Uma execução agendada que o GitHub\ndescarta por carga não aparece como falha, porque não existe execução nenhuma\npara falhar. E quando uma execução falha de fato, o GitHub manda o aviso para\n",[33,575,577],{"href":107,"rel":576},[37],"a pessoa que editou a linha do cron por último",".\nSe foi um freelancer que montou isso para você, o e-mail sobre o seu backup vai\nparar na caixa de entrada dele.",[192,580],{"alt":581,"caption":582,"src":583},"Um job concluído, marcado com um visto verde. Sai dele uma linha que se divide em dois painéis de arquivo idênticos. No arquivo de cima, todas as linhas estão preenchidas. No de baixo, as linhas acabam depois de duas e o resto são contornos tracejados vazios.","Os dois arquivos saíram de uma execução que terminou sem erro. Nada na execução diz qual deles você tem.","\u002Fblog\u002Fsupabase-backup-github-action\u002Fgreen-run-short-file-1600x740.png",[10,585,586,587,591],{},"Só uma restauração separa um do outro. Rode os três arquivos num projeto\ndescartável do Supabase ou num local, compare o número de linhas das tabelas que\nimportam para você com as de verdade e entre como um usuário real.\n",[33,588,590],{"href":589},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Como restaurar um backup do Supabase","\ntem os comandos, na ordem que o Supabase dá. Faça isso uma vez agora, e de novo\nsempre que mudar o workflow.",[10,593,594,595,600],{},"Você também pode deixar cada execução cuidar da restauração e da contagem.\nPublicamos uma versão desse workflow como uma GitHub Action de código aberto,\n",[33,596,599],{"href":597,"rel":598},"https:\u002F\u002Fgithub.com\u002FReeve-page\u002Fsupabase-backup-action",[37],"Reeve-page\u002Fsupabase-backup-action",".\nEla faz os mesmos três dumps, guarda a cópia como artefato do workflow ou\nnum bucket S3 ou R2, depois a reproduz num banco Supabase descartável no runner\ne compara o número de linhas de cada tabela com o arquivo. A execução só fica\nverde quando cada tabela voltou com as linhas que o arquivo tem:",[73,602,605],{"className":603,"code":604,"language":78,"meta":79},[76],"- uses: Reeve-page\u002Fsupabase-backup-action@v1\n  with:\n    db-url: ${{ secrets.SUPABASE_DB_URL }}\n",[68,606,604],{"__ignoreMap":79},[10,608,609],{},"Ela é gratuita e tem licença MIT. Cada execução continua baixando o banco\ninteiro, então a conta de egress acima vale do mesmo jeito, e testar o login\ncontinua sendo com você.",[25,611,613],{"id":612},"quando-devo-parar-de-fazer-isso-por-conta-própria","Quando devo parar de fazer isso por conta própria?",[10,615,616],{},"Quando a conta para de fechar, quando o arquivo não cabe mais no repositório ou\nquando ninguém restaura as cópias. Qualquer uma delas basta.",[86,618,619,625,633,639],{},[89,620,621,624],{},[17,622,623],{},"Seu banco passou da cota gratuita."," O Pro sobe o egress para 250 GB e\nacrescenta os backups diários do próprio Supabase, guardados por sete dias,\nque se restauram com um botão. Deixe o workflow rodando ao lado deles, porque\nessas cópias moram dentro da conta.",[89,626,627,632],{},[17,628,424,629,631],{},[68,630,443],{}," está chegando a 100 MiB."," Passar isso para um bucket é mais\nYAML, e mais coisa para alguém manter funcionando.",[89,634,635,638],{},[17,636,637],{},"Ninguém nunca restaurou uma cópia."," O workflow vai continuar escrevendo\narquivos, abram eles ou não.",[89,640,641,644],{},[17,642,643],{},"Seus usuários enviam arquivos."," O workflow não chega até eles, e o job que\nchega é mais um para manter vivo.",[25,646,648],{"id":647},"onde-o-reeve-care-entra","Onde o Reeve Care entra",[10,650,651],{},[17,652,653],{},"O Care faz a cópia num horário fixo, guarda fora da sua conta do Supabase e\nconfere cada cópia antes de ela contar.",[86,655,656,662,668,674,680],{},[89,657,658,661],{},[17,659,660],{},"Todo dia no Care, e com mais frequência nos planos acima dele",", sem nada no\nseu repositório e sem connection string numa CI.",[89,663,664,667],{},[17,665,666],{},"Relida e contada."," Cada cópia é aberta e contada contra o que entrou nela,\ne a data no seu painel é a da última cópia que passou nessa conferência, nunca\na da última execução.",[89,669,670,673],{},[17,671,672],{},"Suas contas estão dentro",", e os seus arquivos enviados vêm junto assim que\nvocê conecta uma credencial do Storage.",[89,675,676,679],{},[17,677,678],{},"Restaurar é um botão",", e uma cópia do estado atual é feita antes de\nqualquer coisa ser substituída.",[89,681,682,685,686,689,690,692,693,696],{},[17,683,684],{},"Qualquer cópia pode ser baixada como zip"," com ",[68,687,688],{},"schema.sql",", ",[68,691,443],{}," e\n",[68,694,695],{},"roles.sql",", os mesmos três arquivos que este workflow faz, mais o número de\nlinhas de cada tabela.",[10,698,699,700,704,705,709],{},"O Care guarda uma cópia do seu banco do Supabase. A cópia, a conferência e a\nrestauração estão desenhadas passo a passo na\n",[33,701,703],{"href":702},"\u002Fsupabase-backups","página de backups do Supabase",", e\n",[33,706,708],{"href":707},"\u002Fpricing","o que cada plano inclui"," está na página de preços.",[25,711,713],{"id":712},"o-que-fazer-esta-semana","O que fazer esta semana",[715,716,717],"key-takeaways",{},[86,718,719,722,728,731,740,743],{},[89,720,721],{},"Veja o tamanho do seu banco e o egress do mês passado, e escolha o horário pela tabela antes de escrever a linha do cron.",[89,723,724,725,727],{},"Crie um repositório privado que só tenha o workflow, e coloque a string do Session pooler no secret ",[68,726,144],{}," dele.",[89,729,730],{},"Se você começou pelo exemplo do Supabase, apague os gatilhos de push e pull request e tire o cron da hora cheia.",[89,732,733,734,736,737,739],{},"Rode uma vez na mão pela aba Actions, depois procure no ",[68,735,443],{}," por ",[68,738,539],{}," e por uma tabela que você sabe que tem linhas.",[89,741,742],{},"Restaure uma cópia num projeto descartável e entre como um usuário de verdade.",[89,744,745],{},"Copie os seus arquivos do Storage com um job à parte.",[10,747,748,749,753],{},"Antes de fechar esta aba, abra no Supabase a página Usage da sua organização e\nleia o egress do mês passado. Esse número, ao lado do tamanho do seu banco, é o\nque escolhe a sua linha do cron. E se você ainda está comparando o caminho\ngratuito com os pagos,\n",[33,750,752],{"href":751},"\u002Fblog\u002Fsupabase-backup-tools-compared","os quatro tipos de ferramenta de backup do Supabase","\nestão comparados lado a lado.",{"title":79,"searchDepth":755,"depth":755,"links":756},3,[757,759,760,761,762,763,764,765,766,767,768,769],{"id":27,"depth":758,"text":28},2,{"id":62,"depth":758,"text":63},{"id":155,"depth":758,"text":156},{"id":205,"depth":758,"text":206},{"id":247,"depth":758,"text":248},{"id":362,"depth":758,"text":363},{"id":470,"depth":758,"text":471},{"id":520,"depth":758,"text":521},{"id":550,"depth":758,"text":551},{"id":612,"depth":758,"text":613},{"id":647,"depth":758,"text":648},{"id":712,"depth":758,"text":713},"Backups","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcover-1200x630.png","Um banco de dados num invólucro do Supabase, um cano que passa por um medidor com o ponteiro na faixa âmbar e uma fila de arquivos noturnos.","Um backup do Supabase com GitHub Action é grátis e serve para muitos apps. O workflow, a connection string certa e o egress de cada execução.",false,"md",[777,780,783,785,788,791],{"q":778,"a":779},"Posso fazer backup do Supabase de graça?","Pode. O Supabase documenta um workflow do GitHub Actions que instala a CLI dele, exporta seus roles, seu schema e seus dados em três arquivos num horário fixo e faz commit deles no repositório. Um repositório privado no GitHub Free ganha 2.000 minutos de Actions por mês, e um dump noturno de um banco pequeno usa uma parte pequena disso. O que o backup gasta de verdade é sua cota de egress no Supabase, porque cada execução baixa o banco inteiro.",{"q":781,"a":782},"Com que frequência um cron de backup do Supabase deve rodar?","Com a frequência que sua cota de egress consegue pagar. Multiplique o tamanho do seu banco pelas execuções do mês: um banco de 100 MB exportado todo dia move cerca de 3 GB, e um de 500 MB cerca de 15 GB. O plano gratuito inclui 5 GB para a organização inteira, divididos com o tráfego do seu próprio app. Coloque o job num minuto que não seja a hora cheia, porque o GitHub diz que execuções agendadas no início de cada hora podem atrasar, e algumas ser descartadas.",{"q":206,"a":784},"Conta. O Supabase conta como egress os dados que qualquer um dos seus serviços manda para fora, e um dump pelo connection pooler entra como Shared Pooler Egress na mesma cota do seu tráfego de API. A cota é da organização inteira, não de um projeto só. No plano gratuito, estourar essa cota repetidas vezes termina em restrições para todos os projetos da organização.",{"q":786,"a":787},"Por que meu workflow de backup falha na primeira execução?","Duas falhas são típicas desta montagem. A primeira é a connection string: a conexão direta do Supabase usa IPv6, a menos que você pague o add-on de IPv4, e o Supabase lista o GitHub Actions entre os serviços que só alcançam IPv4, então use a string do Session pooler. A segunda pega os workflows que chamam o pg_dump diretamente: o cliente PostgreSQL 16 do runner se recusa a exportar um projeto em Postgres 17 e para com aborting because of server version mismatch.",{"q":789,"a":790},"Posso fazer commit do meu backup do Supabase no meu repositório do GitHub?","Num privado, pode, e é isso que o workflow do Supabase faz. Num público, nunca, e o Supabase diz isso duas vezes na mesma página. Dê a ele um repositório só dele que ninguém mais consiga ler, porque o arquivo de dados guarda os e-mails dos seus usuários. E conte com ter que mudar quando o banco crescer: o GitHub avisa acima de 50 MiB e recusa arquivos acima de 100 MiB.",{"q":792,"a":793},"Como sei se o arquivo de backup presta?","Restaure. Uma execução verde significa que o job terminou sem erro, e um dump do projeto errado ou um dump sem nenhuma linha terminam do mesmo jeito. Rode os três arquivos num projeto descartável do Supabase ou num local, compare o número de linhas das tabelas que importam para você e entre como um usuário de verdade. Essa é a verificação que diz se o arquivo abre.","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",[796,797,798,799,800,801,802,803],"supabase backup github action","automatizar backup supabase","backup supabase cron","backup gratis supabase","supabase pg_dump github actions","backup agendado supabase","workflow backup supabase","backup automatico supabase plano gratuito",{},true,"Backup grátis do Supabase com uma GitHub Action","\u002Fblog\u002Fsupabase-backup-github-action","2026-09-27",{"title":5,"description":773},"blog\u002Fsupabase-backup-github-action",[812,813,814],"Uma GitHub Action de backup do Supabase roda a CLI do Supabase num horário fixo e faz commit do dump num repositório privado. Não custa nada, e para muitos apps é a resposta certa.","Cada execução baixa seu banco de dados inteiro, e o Supabase conta isso como egress. O plano gratuito inclui 5 GB por mês para a organização inteira, e um dump diário de um banco perto do limite de 500 MB gasta cerca de três vezes isso.","O exemplo do próprio Supabase se conecta com uma string que os runners do GitHub não alcançam. Coloque a string do Session pooler no secret e restaure uma cópia antes de confiar nas outras.","2026-10-05","rkrUdeLM9XJhlQ-CJxl0tepMWW0V2Eavk39VL5Wf2Bo",[818,825,831,837,843,849,854,860,866,872,878,884,889,895,896,901,906,912,918,923,929,935,941,947,953,959,965,971,976,982,988,994,1000,1006,1012,1018,1024,1030,1036,1042,1048,1053,1059,1065,1071,1077,1083,1089,1095,1100,1106,1112,1118,1124,1129,1135,1141,1147,1152,1158],{"path":819,"title":820,"description":821,"published":822,"category":823,"image":824,"draft":774},"\u002Fblog\u002Fbase44-security-scan","Scan de segurança do Base44: o que só ele enxerga","O scan de segurança do Base44 verifica sete tipos de problema por dentro. Esta é a metade que ele lê e mais ninguém, e a metade que ele nunca olha.","2026-10-10","Noções de segurança","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":826,"title":827,"description":828,"published":829,"category":823,"image":830,"draft":774},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Sua chave de API vazou. A ordem em que agir","Uma chave de API vazou e você não sabe o que fazer primeiro. Nem toda chave no seu frontend é um vazamento, e a ordem importa mais que a pressa.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":832,"title":833,"description":834,"published":835,"category":823,"image":836,"draft":774},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" sem desligar o RLS","\"Infinite recursion detected in policy for relation\" significa que a sua policy perguntou à tabela que ela protege. Veja como quebrar o círculo.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":838,"title":839,"description":840,"published":841,"category":823,"image":842,"draft":774},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\" no Supabase, e a correção errada","\"No API key found in request\" significa que sua requisição chegou ao Supabase sem chave. Quase toda resposta aponta para as regras do seu banco.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":844,"title":845,"description":846,"published":847,"category":823,"image":848,"draft":774},"\u002Fblog\u002Fis-base44-safe","O Base44 é seguro? O que vimos em 5.442 apps Base44","O Base44 é seguro? Rodamos nove verificações em 5.442 apps Base44 no ar. Quase todas tiraram B por motivos que o dono nunca escolheu.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":850,"title":851,"description":852,"published":815,"category":823,"image":853,"draft":774},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","Esconder uma chave de API: mova para uma Edge Function do Supabase","Esconder uma chave de API é tirá-la do navegador, e uma Edge Function do Supabase é o menor lugar para guardá-la. Dois passos em volta pesam mais.","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":855,"title":856,"description":857,"published":858,"category":823,"image":859,"draft":774},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Seu arquivo .env está exposto? Os doze caminhos para testar","Seu arquivo .env está exposto no seu próprio servidor web? Doze endereços dizem isso em um minuto, e um acerto significa que tudo nele já é público.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":861,"title":862,"description":863,"published":864,"category":823,"image":865,"draft":774},"\u002Fblog\u002Fis-v0-safe","Segurança do v0: os 1.790 aplicativos v0 escaneados tiraram A","A segurança do v0 medida em 1.790 aplicativos v0 no ar: todos tiraram A. Só 17 citavam um banco de dados, e é sobretudo isso que esse A mede.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":867,"title":868,"description":869,"published":870,"category":823,"image":871,"draft":774},"\u002Fblog\u002Fis-bolt-safe","O Bolt é seguro? O que vimos em 1.123 aplicativos Bolt","O Bolt é seguro? Passamos 1.123 aplicativos Bolt no ar por nove verificações. A hospedagem saiu limpa. Os achados: chaves e tabelas abertas nos aplicativos.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":873,"title":874,"description":875,"published":876,"category":823,"image":877,"draft":774},"\u002Fblog\u002Fis-supabase-down-or-your-app","O Supabase caiu ou o problema é o seu app? Como saber","O Supabase caiu ou o problema é o seu app? Um projeto pausado, um banco cheio e um erro seu parecem iguais. Quatro verificações separam os casos.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":879,"title":880,"description":881,"published":882,"category":823,"image":883,"draft":774},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","O Supabase criptografa meus dados? Sim. Veja o que isso impede","O Supabase criptografa os dados? Sim: AES-256 em repouso, TLS em trânsito, SOC 2 e ISO 27001. O que cada um cobre, e o vazamento que nenhum deles impede.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":230,"title":885,"description":886,"published":887,"category":823,"image":888,"draft":774},"Quanto custa o Supabase? Os limites do plano gratuito","Quanto custa o Supabase: o plano gratuito tem 500 MB de banco, 5 GB de egress e nenhum backup. O que acontece em cada limite e o que o Pro de $25 muda.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":890,"title":891,"description":892,"published":893,"category":770,"image":894,"draft":774},"\u002Fblog\u002Ftest-your-supabase-backup","Teste o backup do seu Supabase antes do dia em que precisar","Como testar o backup do seu Supabase: restaurar num projeto de teste, contar as linhas, entrar e procurar a linha que falta num arquivo cortado.","2026-09-28","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":807,"title":5,"description":773,"published":808,"category":770,"image":794,"draft":774},{"path":54,"title":897,"description":898,"published":899,"category":770,"image":900,"draft":774},"Por que você não consegue baixar seu backup do Supabase","Você não consegue baixar seu backup do Supabase num projeto atual, porque a cópia diária é um snapshot físico. Como conferir e como ter uma cópia só sua.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":902,"title":903,"description":904,"published":899,"category":823,"image":905,"draft":774},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": o grant que falta","A partir de 30 de outubro, uma tabela nova no Supabase responde \"permission denied for table\" até receber um grant. O e-mail mostra só metade.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":907,"title":908,"description":909,"published":910,"category":823,"image":911,"draft":774},"\u002Fblog\u002Fopen-api-endpoint-exposed","Um endpoint de API aberto é um problema? Leia o JSON","Seu scan apontou um endpoint de API aberto. Se isso importa depende do que voltou, e a maioria dos que encontramos era da própria plataforma.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":913,"title":914,"description":915,"published":916,"category":823,"image":917,"draft":774},"\u002Fblog\u002Flovable-security-scan","Escaneamento de segurança do Lovable: o que ele não prova","Escaneamento de segurança do Lovable: o que o Quick scan e o Deep scan checam, quando cada um roda, e a única coisa que nenhum escaneamento por dentro prova.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":491,"title":919,"description":920,"published":921,"category":770,"image":922,"draft":774},"Por que seu dump do Supabase não tem usuários dentro","Rode supabase db dump sozinho e você recebe a forma do seu banco e nenhuma das linhas dele, sem o schema auth onde seus usuários moram.","2026-09-23","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":924,"title":925,"description":926,"published":927,"category":823,"image":928,"draft":774},"\u002Fblog\u002Fdomain-and-certificate-expiry","Domínio expirado, site fora do ar: o que acontece agora","Seu domínio expirou e seu site está fora do ar. O relógio que começa a correr, por que o certificado é o problema menor, e como conferir os dois.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":930,"title":931,"description":932,"published":933,"category":823,"image":934,"draft":774},"\u002Fblog\u002Fis-lovable-safe","O Lovable é seguro? O que vimos em 18.554 aplicativos Lovable","O Lovable é seguro? Passamos 18.554 aplicativos Lovable no ar por nove verificações. A plataforma foi a mais limpa de cinco. Os achados estavam nos aplicativos.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":936,"title":937,"description":938,"published":939,"category":823,"image":940,"draft":774},"\u002Fblog\u002Fvibe-coded-app-security-checklist","O checklist de segurança do vibe coding, em nove verificações","Um checklist de segurança do vibe coding com nove itens, cada um verificável no seu app de fora por qualquer pessoa, e cada um com um teste de uma linha.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":942,"title":943,"description":944,"published":945,"category":823,"image":946,"draft":774},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Uma chave secreta da Stripe no frontend pode mover dinheiro","Uma chave secreta da Stripe exposta no seu frontend pode reembolsar, cobrar e ler cada ficha de cliente que você tem. Sua chave pk_live_ é que deve estar aí.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":948,"title":949,"description":950,"published":951,"category":823,"image":952,"draft":774},"\u002Fblog\u002Fvite-and-next-public-env-vars","Variáveis de ambiente do Vite expostas: o prefixo diz publique isto","Variáveis de ambiente do Vite expostas no seu app: fizeram o que o prefixo pediu. VITE_ e NEXT_PUBLIC_ significam publique isto, e a IA nunca soube o custo.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":954,"title":955,"description":956,"published":957,"category":823,"image":958,"draft":774},"\u002Fblog\u002Fbase44-source-maps","Segurança no Base44: o que um scan aponta e o que é seu para corrigir","Segurança no Base44 em 5.438 apps escaneados: três achados em quase todos são da plataforma, o source map é o selo do Base44, e a sua parte é uma lista curta.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":960,"title":961,"description":962,"published":963,"category":823,"image":964,"draft":774},"\u002Fblog\u002Fis-cursor-ai-safe","O Cursor AI é seguro? O editor, o código e o app que você publicou","O Cursor AI é seguro? Três perguntas em uma busca: o que o Cursor guarda, o que o código que ele escreve erra, e se o app que você publicou está aberto.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":966,"title":967,"description":968,"published":969,"category":823,"image":970,"draft":774},"\u002Fblog\u002Fis-replit-safe","O Replit é seguro? O que vimos em 3.042 aplicativos Replit no ar","O Replit é seguro? Passamos 3.042 aplicativos Replit no ar por nove verificações externas. Os achados estavam no aplicativo publicado, não no host.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":527,"title":972,"description":973,"published":974,"category":770,"image":975,"draft":774},"Supabase storage backup: sua cópia do banco não tem nenhum arquivo","Um Supabase storage backup é uma tarefa à parte. Os backups do banco guardam a lista dos seus arquivos e nenhum deles, então cada upload fica quebrado.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":977,"title":978,"description":979,"published":980,"category":770,"image":981,"draft":774},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Point-in-time recovery do Supabase: preço e limites","O point-in-time recovery do Supabase rebobina seu banco para qualquer segundo da última semana. Custa $100 por mês além do Pro e cobre só o banco.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":983,"title":984,"description":985,"published":986,"category":770,"image":987,"draft":774},"\u002Fblog\u002Fsupabase-project-paused-recover","Projeto Supabase pausado? Seus dados continuam lá","O Supabase pausou seu projeto depois de uma semana sem atividade. Nada foi apagado, Restaurar fica ao lado do nome e você tem um ano antes disso mudar.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":989,"title":990,"description":991,"published":992,"category":823,"image":993,"draft":774},"\u002Fblog\u002Fsafest-ai-app-builder","Qual builder de apps com IA é mais seguro? 30.998 apps testados","Qual builder de apps com IA é mais seguro? Escaneamos 30.998 apps no ar do Lovable, Base44, Replit, v0 e Bolt. O builder não é o que decide sua nota.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":995,"title":996,"description":997,"published":998,"category":823,"image":999,"draft":774},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Ative Row Level Security em toda tabela do Supabase e comprove","Ativar Row Level Security no Supabase sem política fecha a tabela por completo. Uma política sem a chave ligada não faz nada. Aqui está o SQL, e o teste.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":1001,"title":1002,"description":1003,"published":1004,"category":823,"image":1005,"draft":774},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": o que o aviso não vê","O Supabase marca \"RLS disabled in public\" como erro. Ele não diz nada sobre a política de leitura que deixa a sua tabela igualmente aberta.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":1007,"title":1008,"description":1009,"published":1010,"category":823,"image":1011,"draft":774},"\u002Fblog\u002Frotate-supabase-service-role-key","Como rotacionar uma chave service_role do Supabase vazada","O Supabase manda fechar o vazamento primeiro. Outros guias mandam rotacionar agora. O que vale depende de para onde a sua chave service_role vazou.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":1013,"title":1014,"description":1015,"published":1016,"category":823,"image":1017,"draft":774},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Scanners de segurança para vibe coding comparados, o nosso incluído","O melhor scanner de segurança para vibe coding depende de três perguntas que nenhuma lista de recursos responde. Dez ferramentas comparadas, com preços.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":1019,"title":1020,"description":1021,"published":1022,"category":823,"image":1023,"draft":774},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: faça você mesmo as cinco verificações","Um Supabase security checker lê o seu app publicado em vez das configurações do projeto. Aqui estão as cinco verificações e como fazer cada uma sozinho.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":1025,"title":1026,"description":1027,"published":1028,"category":823,"image":1029,"draft":774},"\u002Fblog\u002Fvibe-coding-security-scanner","Scanner de segurança para vibe coding: o que ele não vê","Um scanner de segurança para vibe coding lê seu app no ar, de fora. O que isso cobre, as quatro coisas que ele não consegue ver e como ler o resultado.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":1031,"title":1032,"description":1033,"published":1034,"category":823,"image":1035,"draft":774},"\u002Fblog\u002Fmissing-security-headers","Cabeçalhos de segurança faltando: quando isso importa","Cabeçalhos de segurança faltando é o achado que nosso scanner mais imprime. Contra o que eles protegem e quando são a linha menos urgente do relatório.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":1037,"title":1038,"description":1039,"published":1040,"category":823,"image":1041,"draft":774},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Sua chave de API da OpenAI está exposta no frontend. Troque-a.","Uma chave de API da OpenAI exposta no frontend não pode ser presa a um domínio. Troque-a hoje, mova a chamada para o seu servidor e limite o gasto.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":1043,"title":1044,"description":1045,"published":1046,"category":823,"image":1047,"draft":774},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","Chave de API exposta no frontend: o que 30.998 apps entregam","Uma chave de API exposta no seu frontend costuma ser uma chave do Google Maps. Escaneamos 30.998 apps vibe-coded e contamos quais segredos vazam de verdade.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":751,"title":1049,"description":1050,"published":1051,"category":770,"image":1052,"draft":774},"Ferramentas de backup do Supabase comparadas, a nossa incluída","Quatro tipos de ferramenta de backup do Supabase, o que cada uma copia de verdade e quando uma GitHub Action gratuita ganha de pagar, nós inclusive.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":1054,"title":1055,"description":1056,"published":1057,"category":823,"image":1058,"draft":774},"\u002Fblog\u002Freplit-secrets-explained","Como usar secrets no Replit, e o que ainda assim é publicado","Como usar secrets no Replit: adicionar um, ler de volta e resolver as duas causas do undefined. E as chaves que a ferramenta Secrets não consegue proteger.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":1060,"title":1061,"description":1062,"published":1063,"category":770,"image":1064,"draft":774},"\u002Fblog\u002Fback-up-supabase-free-tier","Backups do plano gratuito do Supabase: como fazer sem terminal","No plano gratuito do Supabase não existe backup nenhum: a cópia é você que faz. Como fazer uma pelo painel e o que a rota do CSV deixa para trás.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":1066,"title":1067,"description":1068,"published":1069,"category":823,"image":1070,"draft":774},"\u002Fblog\u002Fis-supabase-secure","O Supabase é seguro? É. Seu projeto é outra pergunta","O Supabase é seguro? A plataforma é auditada, criptografada e passa por pentests. A documentação deles diz onde isso termina e começam suas configurações.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":1072,"title":1073,"description":1074,"published":1075,"category":823,"image":1076,"draft":774},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Onde ficam as chaves de API do Supabase: anon, service_role e URL","A URL do projeto, a chave anon e a chave service_role ficam todas numa página do painel. Aqui está onde ela fica, e qual dos quatro valores vai no seu app.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":1078,"title":1079,"description":1080,"published":1081,"category":823,"image":1082,"draft":774},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","New row violates row-level security policy no Supabase. E agora?","\"New row violates row-level security policy\" significa que o Supabase recusou uma escrita. O conserto rápido reabre a tabela para qualquer um.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":1084,"title":1085,"description":1086,"published":1087,"category":823,"image":1088,"draft":774},"\u002Fblog\u002Fcors-wildcard-security-risk","Um curinga CORS é um risco de segurança? Quase nunca.","Um curinga CORS é um risco de segurança? Em geral é o padrão do seu builder e não entrega nada que o seu servidor já não desse a qualquer um que pedisse.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":1090,"title":1091,"description":1092,"published":1093,"category":770,"image":1094,"draft":774},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Branching do Supabase não é backup. Ele só anda para a frente.","Por que o branching do Supabase não é backup: um branch começa sem os seus dados e um merge só leva o esquema. Para que ele serve e o que usar no lugar.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":589,"title":1096,"description":1097,"published":1098,"category":770,"image":1099,"draft":774},"Como restaurar um backup do Supabase, e o que quebra depois","Como restaurar um backup do Supabase pelo painel ou por um arquivo de dump, o que a restauração substitui e por que o seu app pode continuar quebrado no fim.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":1101,"title":1102,"description":1103,"published":1104,"category":823,"image":1105,"draft":774},"\u002Fblog\u002Fsupabase-storage-bucket-public","Seu bucket do Supabase Storage é público. Isso é um problema?","Um bucket público do Supabase Storage significa que quem tem a URL de um arquivo pode abri-lo. Não significa que alguém possa listar o que está lá dentro.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":1107,"title":1108,"description":1109,"published":1110,"category":823,"image":1111,"draft":774},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","Uma chave de API do Google no frontend é um problema?","Uma chave de API do Google exposta no seu frontend é a chave que nosso scanner mais encontra, e quase sempre está tudo bem. Um ajuste gratuito decide isso.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":1113,"title":1114,"description":1115,"published":1116,"category":770,"image":1117,"draft":774},"\u002Fblog\u002Fai-agent-deleted-my-database","Um agente de IA apagou meus dados do Supabase. O que eu recupero?","Um agente de IA apagou dados do seu banco. O que você recupera já estava decidido antes de ele rodar, e os próximos minutos decidem o resto.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":1119,"title":1120,"description":1121,"published":1122,"category":823,"image":1123,"draft":774},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","Qualquer um consegue ler seu banco Supabase? Testamos 3.680 apps","Qualquer um consegue ler seu banco de dados Supabase sem fazer login? Escaneamos 30.998 apps no ar criadas com builders de IA e medimos quantas dizem que sim.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":1125,"title":1126,"description":1127,"published":1122,"category":823,"image":1128,"draft":774},"\u002Fblog\u002Fsource-maps-exposed-in-production","Source maps expostos: seu app está publicando o código original","Um source map exposto deixa qualquer um ler o código original do seu app, comentários incluídos. A verificação de 30 segundos e o que importa de verdade.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":1130,"title":1131,"description":1132,"published":1133,"category":823,"image":1134,"draft":774},"\u002Fblog\u002Fsupabase-new-api-keys","As novas chaves de API do Supabase: qual vai no seu app?","O Supabase trocou anon e service_role por chaves publicáveis e secretas. Qual delas pertence ao seu app e qual nunca deve estar lá?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":1136,"title":1137,"description":1138,"published":1139,"category":770,"image":1140,"draft":774},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","O Supabase faz backup do meu banco de dados? Depende do plano.","O Supabase faz backup do seu banco de dados? Todo dia nos planos pagos, e nada no gratuito. Como descobrir o que você tem e o que essa cópia não cobre.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":1142,"title":1143,"description":1144,"published":1145,"category":823,"image":1146,"draft":774},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","O Supabase Row Level Security está ligado. A tabela continua pública.","Ligar o Supabase Row Level Security não protege uma tabela. Quem protege são as políticas, e a que consertou o seu app pode deixar qualquer um entrar.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":1148,"title":1149,"description":1150,"published":1145,"category":770,"image":1151,"draft":774},"\u002Fblog\u002Fversion-history-is-not-a-backup","O histórico de versões não é backup. Ele não desfaz um delete.","Lovable e Bolt guardam um histórico de versões do seu código. Seu banco de dados é um serviço à parte, e voltar atrás não traz os seus dados de volta.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":1153,"title":1154,"description":1155,"published":1156,"category":770,"image":1157,"draft":774},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Três formas de fazer backup de um banco Supabase, e o que falta","O painel, o pg_dump e um serviço gerenciado. O que cada um salva de verdade, o que deixa de fora sem avisar e qual sobrevive a perder a conta.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":1159,"title":1160,"description":1161,"published":1156,"category":823,"image":1162,"draft":774},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Quais chaves de API são seguras no navegador e quais não são","Sua chave anon do Supabase foi feita para ser pública. Sua chave service_role não, e ela ignora todas as regras que você criar. Como diferenciar as duas.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1791618971769]