Backups
Supabase storage backup: у копії бази даних немає жодного файлу
Supabase storage backup це окрема робота. Копії бази даних зберігають список ваших файлів і жодного з них, тож після відновлення кожне завантаження зламане.

Коротко
- Supabase storage backup це окрема робота, відділена від резервної копії бази даних. Кожна копія, яку робить Supabase, на будь-якому плані, містить рядок, що описує кожен завантажений файл, і жодного з самих файлів.
- Відновіть лише базу даних, і ви отримаєте робочий застосунок, у якому кожен аватар, кожен рахунок і кожне завантаження відкривається помилкою, бо файл, на який вони вказують, ніколи не був у копії.
- Сумісний із S3 ендпоїнт це спосіб скопіювати файли назовні. Шлях назад лежить через сам Storage, який записує відповідний рядок, щойно прибуває кожен файл, тож список і файли не можуть розійтися.
Ви налаштували резервні копії для свого застосунку на Lovable чи Bolt, або платите за план Supabase, який їх робить, і слово зробило свою справу: ви перестали хвилюватися. Потім відновлення, або переїзд у новий проєкт, і застосунок повертається зі зламаним зображенням там, де раніше було кожне фото профілю. Кожна таблиця і кожен рядок на місці. Фотографії зникли, а з ними кожен рахунок, кожен експорт і кожен вкладений файл, який будь-коли завантажив користувач.
Ось та частина, яку слово «резервна копія» приховує: Supabase storage backup це окрема робота, бо резервна копія бази даних містить рядок для кожного файлу, який завантажили ваші користувачі, і жодного з файлів. Рядок лежить у вашій базі даних. Файл лежить у Storage, окремому сервісі, і жодна копія бази даних на жодному плані туди не сягає. Ця стаття пояснює, як зняти ту другу копію, і в якому порядку обидві половини повертаються назад, бо саме на цьому все ламається навіть тоді, коли у вас є обидві.
Допомагає уявити бібліотеку. Каталог це шухляда з картками, по одній на кожну книжку, і кожна картка каже, на якій полиці книжка стоїть. Книжки стоять на полицях. Резервна копія бази даних копіює шухляду.
Чи робить Supabase резервні копії моїх файлів у Storage?
Ні, на жодному плані. Документація Supabase про резервні копії каже, що копії не містять файлів, збережених через Storage API, лише їхні метадані в базі даних, а point-in-time recovery це функція бази даних, тож те саме речення покриває і його.
Що кожна копія таки містить, так це список. Supabase тримає у вашій базі
Postgres таблицю з назвою storage.objects, по одному рядку на файл у кожному
бакеті: у якому бакеті він лежить, його шлях, хто його завантажив, який він
завбільшки і коли прибув. Ця таблиця копіюється разом з усім іншим, і саме тому
відновлений проєкт виглядає таким повним. Кожна картка в шухляді.
Байти кожного файлу деінде. Вони живуть в обʼєктному сховищі, окремому сервісі поруч із вашою базою даних, і інструмент, який копіює базу даних, ніколи його не читає. Безкоштовний план не робить жодних автоматичних копій, тож там питання навіть не постає; від Pro і вище щоденна копія має ваші рядки і жодного з ваших завантажень.
Де Supabase зберігає ваші файли
У двох місцях, і резервна копія бази даних сягає одного з них.
Коли користувач завантажує аватар, ваш застосунок передає файл у Storage.
Storage записує байти в обʼєктне сховище під назвою бакета і шляхом, і тією
самою операцією записує в storage.objects рядок, який його описує. Ваш
застосунок потім тримає той шлях в одній зі своїх таблиць, скажімо в рядку
profiles зі стовпцем avatar_url, і будує з нього посилання щоразу, коли
зображення потрібне.
Отже, одне завантажене зображення це три речі: байти в обʼєктному сховищі,
рядок у storage.objects, який веде Storage, і шлях у вашій власній таблиці.
Резервна копія бази даних несе останні дві. Відновіть її, і ваш застосунок має
кожен шлях, а Storage має кожен рядок, і посилання, яке вони разом будують,
вказує на місце, де нічого немає.
Ось чому цей збій такий тихий. Кожен рядок узгоджується з кожним іншим, кожен підрахунок сходиться, і кожна перевірка, яка читає базу даних, проходить, включно з кроком верифікації у більшості інструментів резервного копіювання, бо файлів ніколи не було всередині того, що перевірялося.
Як виглядає відновлення лише з половиною
Проєкт, який проходить кожну перевірку і показує зламане зображення всюди, де мав би зʼявитися файл.
Відновлення звітує про успіх, бо зробило те, про що його просили: таблиці на місці, кількість рядків сходиться. Відкрийте панель, і Storage перелічує кожен бакет і кожен файл у ньому, з розмірами й датами, бо той перелік читається з таблиці, яку відновлення щойно повернуло. Власний посібник Supabase про відновлення копії з панелі в новий проєкт описує саме цей стан: бакети й метадані файлів зʼявляються, а обʼєктів за ними немає.
Дізнаєтеся ви про це буденно. Сторінка команди показує ряд іконок зламаного зображення там, де були аватари. Клієнт відповідає на минуломісячний лист із рахунком, що посилання відкриває помилку. Хтось клацає файл у переглядачі Storage, і завантаження не вдається. Картка каже: полиця чотири, третя зліва, а полиця чотири порожня.
Ніщо не попереджає вас до цієї миті, бо кожне попередження, яке у вас є, підʼєднане до бази даних. Як відновити резервну копію Supabase проходить пʼять способів, якими відновлення повертається зламаним, і файли це той рядок у тій таблиці, для якого немає ради, якщо ви не зняли з них копію.
Поки сторінка Storage відкрита, варто знати, що вона показує сторонньому. Наше безкоштовне сканування читає ваш живий застосунок ззовні і просить у кожного бакета його список файлів, використовуючи лише ключ, який і так лежить у коді вашого застосунку. У серпні 2026 року воно отримало список від 792 із 27 269 застосунків, які змогло перевірити, цифра з нашого власного дослідження. Воно читає назви і ніколи не завантажує файл, триває близько 20 секунд і не потребує облікового запису: проскануйте свій застосунок.
Як зробити резервну копію бакета Supabase Storage?
Через сумісний із S3 ендпоїнт, однією командою, яка копіює цілий бакет у теку, яку тримаєте ви.
Supabase Storage говорить протоколом S3, а це означає, що звичайні інструменти, збудовані для сховища Amazon, працюють і з вашим. Це єдиний крок у цій статті, який відбувається в командному рядку, і його варто зробити раз власноруч, щоб знати, з чого складається копія.
- У панелі Supabase відкрийте налаштування Storage і увімкніть протокол S3. На тій самій сторінці показано URL ендпоїнта і регіон вашого проєкту; скопіюйте обидва звідти, а не звідси.
- На тій сторінці створіть пару ключів доступу S3. Секрет показують лише раз, тож покладіть його в менеджер паролів, перш ніж закрити діалог.
- Встановіть командний рядок AWS, дайте йому обидва ключі як профіль і запустіть по одній синхронізації на бакет:
aws s3 sync s3://avatars ./supabase-files/avatars \
--endpoint-url https://<project-ref>.storage.supabase.co/storage/v1/s3 \
--region <region>
Запустіть її знову завтра, і вона скопіює лише те, що змінилося. rclone
робить ту саму роботу, якщо він вам ближчий; для великого бакета
примітка Supabase з усунення проблем
радить передати --s3-list-version 2, інакше перелік може обірватися
зарано.
Дві речі про цей ключ. Сторінка Supabase про автентифікацію S3 каже, що ключ доступу S3 має повний доступ до кожного бакета і обходить Row Level Security, тож його місце на сервері або на вашій власній машині, і ніколи у вашому застосунку. І він уміє не лише читати, а й писати, бо Supabase не видає для Storage ключа лише на читання; хто його тримає, може видаляти файли так само легко, як і копіювати. Поводьтеся з ним так, як поводилися б із ключем service_role.
Потім покладіть теку кудись поза вашим акаунтом Supabase, з тієї ж причини, з якої копія бази даних має жити поза ним: призупинений проєкт або втрачений вхід забирає з собою кожну копію, збережену всередині того акаунта.
Спочатку файли чи спочатку рядки?
Спочатку база даних, потім файли, і файли повертаються через Storage, щоб рядки записав Storage.
Кожне завантаження, яке проходить через Storage, із вашого застосунку, через
ендпоїнт S3 чи через CLI Supabase, робить дві речі однією операцією: зберігає
байти і записує рядок storage.objects, який їх описує. Книжку ставлять на
полицю, і картку пише та сама рука. Поверніть файли цим шляхом, і рядки прибудуть
разом із ними, і ці двоє не зможуть розійтися.
Інший напрямок такого механізму не має. Копіювання рядків storage.objects
назад інструментом для бази даних пише картки і не ставить нічого на полиці.
Воно ще й ускладнює наступний крок: за замовчуванням Storage відмовляє
завантаженню на шлях, який уже має рядок, з помилкою про те, що ресурс уже
існує, а
посібник Supabase із завантажень
каже, що це обходять, увімкнувши перезапис. Тож коли відновлення бази даних уже
повернуло рядки, а саме це й пропонує зробити власний посібник Supabase з
міграції, копіювання файлів, що йде після нього, мусить мати дозвіл на
перезапис.
Отже, порядок:
- Відновіть базу даних так, як описує та стаття.
- Скопіюйте файли назад через Storage, командою
aws s3 syncу зворотному напрямку (спочатку тека, потім бакет) або командоюsupabase storage cp -r, з увімкненим перезаписом. Бакет, якого більше немає, треба створити заздалегідь, з тією самою назвою і тим самим налаштуванням публічності. - Відкрийте файл, а потім іще кілька.
Найчистіша версія цього взагалі пропускає відтворення storage.objects на
кроці бази даних і дає завантаженням записати кожен рядок наново, тож ніколи
нічого не доводиться перезаписувати. Саме так робить наше власне відновлення.
Для цього копію треба відфільтрувати перед відтворенням, а це крок для
інструмента, який виконує відновлення.
Як перевірити, що у вас є обидві половини
Відкриваючи файли, бо кожен список, який ви можете витягти, читається з таблиці.
Переглядач файлів у панелі, запит до storage.objects і кількість рядків у
звіті про резервну копію описують шухляду, і після відновлення лише бази даних
шухляда бездоганна. Єдиний запит, який торкається полиці, це запит на сам
файл.
Тож після відновлення, і після першої копії, яку ви знімете, відкривайте файли. Візьміть жменю з кожного бакета, включно з найстарішими, і відкрийте їх через застосунок так, як це зробив би користувач. Файл, який відкрився, повернувся. Файл, який дає помилку, ніколи там не був, хай що каже список.
Що зробити цього тижня
Що робити
- Відкрийте Storage у панелі Supabase і запишіть кожен бакет і приблизно те, що в ньому лежить. Усе, що завантажив користувач, живе там і в жодній резервній копії бази даних.
- Увімкніть протокол S3, створіть ключ доступу і запустіть по одному
aws s3 syncна бакет у теку поза вашим акаунтом Supabase. Тримайте секрет у менеджері паролів; він видаляє так само легко, як копіює. - Запускайте синхронізацію знову за розкладом, якого ви дотримаєтеся, чи то нагадування в календарі, чи завдання на сервері.
- Запишіть порядок відновлення там, де знайдете: спочатку база даних, потім файли через Storage з увімкненим перезаписом.
- Відновіть один раз у одноразовий проєкт і відкрийте десять файлів, щоб уперше дізнатися, чи працює копія, не під час збою.
Де тут місце Reeve Care
Care копіює файли разом із базою даних, у тому порядку, який описує ця стаття, і повертає їх тим самим шляхом.
- Файли, які завантажили ваші користувачі, теж копіюються, щойно ви підключите бакети Storage свого застосунку на Supabase. Це другий ключ, який просять окремо, бо ключ, що його Supabase видає для Storage, уміє не лише читати, а й писати, і ми радше спитаємо, ніж складемо його в одне з ключем бази даних, який писати не вміє.
- Копіювання файлів іде після того, як копію бази даних перечитано і перевірено, ніколи поруч, тож точка відновлення ніколи не приписує собі файлів, яких не скопіювала. Копія, якій забракло часу, позначається як часткова, зі справжніми числами.
- Кожна точка відновлення записує, який шлях тримав який файл. База даних, повернута на вівторок, отримує файли вівторка, а файл, який і досі на місці, лишають у спокої.
- Відновлення повертає файли через Storage, тож кожен рядок записує те завантаження, яке несе файл. Ніщо з того, що існує сьогодні, не перезаписується і не видаляється, а це означає, що натиснута в паніці кнопка не може знищити те, що ви намагалися врятувати.
- Відновлення це кнопка, і перед стартом воно робить знімок поточного стану, тож навіть у відновлення є власне скасування.
Care починається з $49 на місяць за один застосунок. Це прайсова ціна, а сторінка цін іноді буває нижчою за цифру тут і ніколи вищою.
Як копію знімають, перевіряють і повертають, разом із файлами, крок за кроком намальовано на сторінці про резервні копії Supabase.
Перш ніж закрити цю вкладку, відкрийте Storage у своїй панелі й порахуйте бакети. Кожен із них це набір файлів, якого жодна копія, зроблена Supabase, ніколи не міститиме, і команда синхронізації вище це все, що потрібно, щоб це змінити. Якщо якийсь бакет до того ж виявився доступним для переліку, що отримує сторонній з того списку це наступне, що варто прочитати.
Поширені запитання
Чи робить Supabase резервні копії моїх бакетів Storage?
Ні. Supabase пише це на власній сторінці про резервні копії: копії бази даних не містять файлів, збережених через Storage API, лише рядки бази даних, які їх описують. Це стосується щоденних копій на платних планах і point-in-time recovery. Безкоштовний план не робить жодних автоматичних копій, тож там питання й не постає. Вашим файлам потрібна власна копія на будь-якому плані.
Чи покриває point-in-time recovery Supabase Storage?
Ні. Point-in-time recovery відмотує базу даних, а Storage це окремий сервіс, до якого база тримає лише шляхи. Проєкт, відмотаний на вівторок, вказує на те, що лежить у бакетах сьогодні, і файл, видалений у середу, лишається видаленим після відновлення, яке спрацювало бездоганно.
Як завантажити всі файли з бакета Supabase?
Через сумісний із S3 ендпоїнт. Увімкніть протокол S3 у налаштуваннях Storage у своїй панелі, створіть пару ключів доступу і спрямуйте командний рядок AWS або rclone на ендпоїнт і регіон, надруковані на тій самій сторінці. Одна команда синхронізації копіює цілий бакет у теку, яку тримаєте ви. Панель завантажує по одному файлу за раз, чого вистачає для логотипа і зовсім не вистачає для бакета.
Що таке storage.objects?
Таблиця у вашій базі Postgres з одним рядком на кожен файл у кожному бакеті: у якому бакеті він лежить, його шлях, хто його завантажив, розмір і тип, і коли він прибув. Це покажчик. Байтів самого файлу в ній немає, і саме тому резервна копія бази даних може перелічити кожен ваш файл, не містячи жодного з них.
Якщо я відновлю базу даних, чи повернуться мої файли?
Ні. Відновлення повертає рядки storage.objects, тож панель перелічує кожен файл і ваш застосунок малює кожне посилання, і кожне з них відкривається помилкою, бо файлу за ним ніколи не було в копії. Файли треба повертати окремо, через Storage, з копії, яку ви з них зняли.