PocketBase хранит всё состояние приложения в одной папке pb_data, и это одновременно удобно и опасно: потеряли папку — потеряли пользователей, записи и загруженные файлы. Ниже — что именно нужно бэкапить, как пользоваться встроенными бэкапами, как сделать копию без них и как восстановиться, не испортив базу. Если вы только знакомитесь с платформой, начните с обзора что такое PocketBase и статьи PocketBase как backend.
Что лежит в pb_data
Типичное содержимое каталога:
data.db— основная база SQLite: коллекции, записи, пользователи, настройки приложения. Это главное, что нужно сохранить.auxiliary.db— в новых версиях есть такжеauxiliary.dbс логами запросов и служебными данными. Её потеря обычно не критична, но если логи вам нужны для разборов, бэкапьте и её.storage/— загруженные файлы (аватары, вложения), если вы используете локальное файловое хранилище. Их нет в базе: вdata.dbлежат только имена файлов.backups/— архивы встроенных бэкапов, если они хранятся локально.- Рядом с
.db-файлами могут лежать-walи-shm: PocketBase работает с SQLite в режиме WAL.
Важно: папка pb_migrations с JS- или Go-миграциями — это описание схемы коллекций, и её место в git. Миграции позволяют воссоздать структуру, но не данные. Репозиторий с миграциями не является бэкапом.
Встроенные бэкапы в дашборде
В админке PocketBase (/_/) в разделе Settings → Backups можно:
- создать бэкап вручную — это zip-архив содержимого
pb_data(без самой папкиbackups); - включить автоматические бэкапы по расписанию, заданному cron-выражением, например
0 3 * * *для ежедневного запуска в 03:00; - хранить архивы не на диске сервера, а в S3-совместимом хранилище — у бэкапов отдельные настройки S3, независимые от хранилища файлов.
Плюсы: ничего не нужно ставить, архив включает и базы, и локальные файлы, восстановление делается из того же интерфейса.
Ограничения, которые стоит учитывать:
- Если архивы хранятся в
pb_data/backupsна том же диске, они погибнут вместе с сервером. Включите S3 или копируйте архивы наружу. - Архив целиком, со всеми файлами из
storage/. При большом объёме загрузок каждый бэкап получается тяжёлым и долгим. В этом случае лучше вынести файлы в S3 (см. ниже), а бэкапить только базы. - Во время создания архива приложение может ненадолго ограничивать запись — планируйте бэкапы на время низкой нагрузки.
Бэкап через API
Встроенный бэкап можно запустить и снаружи, например из CI перед деплоем. Нужен токен суперпользователя:
PB_URL=https://pb.example.ru
TOKEN=$(curl -s -X POST "$PB_URL/api/collections/_superusers/auth-with-password" \
-H 'Content-Type: application/json' \
-d "{\"identity\":\"$PB_ADMIN_EMAIL\",\"password\":\"$PB_ADMIN_PASSWORD\"}" \
| jq -r .token)
# создать бэкап с заданным именем
curl -s -X POST "$PB_URL/api/backups" \
-H "Authorization: $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"name":"pre_deploy_20260924.zip"}'
# список бэкапов
curl -s "$PB_URL/api/backups" -H "Authorization: $TOKEN"
Учётные данные передавайте через переменные окружения или секреты CI, а не храните в скрипте. В версиях до 0.23 администраторы были отдельной сущностью, и путь авторизации отличался; сверяйтесь с документацией своей версии.
Бэкап без встроенного механизма
Встроенные бэкапы — не единственный вариант. Если вы хотите хранить версии базы отдельно от файлов или уже используете cron на сервере, делайте копии сами.
Консистентная копия data.db
PocketBase держит базу открытой и пишет в неё постоянно. Простой cp data.db во время работы может дать копию без последних транзакций из -wal или вовсе повреждённый файл. Используйте онлайн-бэкап SQLite — он безопасен при работающем приложении:
sqlite3 /opt/pocketbase/pb_data/data.db ".backup '/var/backups/pb/data-$(date +%F).db'"
sqlite3 /opt/pocketbase/pb_data/auxiliary.db ".backup '/var/backups/pb/aux-$(date +%F).db'"
Подробнее о .backup, VACUUM INTO и режиме WAL — в статье как сделать бэкап SQLite.
Файлы из storage
Для локального хранилища синхронизируйте pb_data/storage в S3 через rclone. Пример remote для Yandex Object Storage в ~/.config/rclone/rclone.conf:
[yos]
type = s3
provider = Other
endpoint = https://storage.yandexcloud.net
region = ru-central1
access_key_id = ...
secret_access_key = ...
rclone sync /opt/pocketbase/pb_data/storage yos:pb-backups/storage
rclone sync удаляет в бакете то, чего нет в источнике. Если пользователь удалил файл по ошибке, синхронизация удалит и копию — включите версионирование объектов в бакете или используйте rclone copy, если удаления не критичны.
Альтернатива — в настройках PocketBase переключить хранение файлов на S3. Тогда загрузки сразу уходят в бакет, storage/ на сервере не растёт, а защиту файлов обеспечивают версионирование и политика хранения бакета. Бэкапить на сервере остаётся только базы.
Скрипт и таймер
#!/usr/bin/env bash
# /usr/local/bin/backup-pocketbase.sh
set -euo pipefail
PB=/opt/pocketbase/pb_data
DIR=/var/backups/pb
TS=$(date +%Y%m%d-%H%M)
mkdir -p "$DIR"
sqlite3 "$PB/data.db" ".backup '$DIR/data-$TS.db'"
sqlite3 "$DIR/data-$TS.db" "PRAGMA quick_check;" | grep -qx ok
gzip "$DIR/data-$TS.db"
aws s3 cp "$DIR/data-$TS.db.gz" "s3://pb-backups/db/data-$TS.db.gz" \
--endpoint-url https://storage.yandexcloud.net
rclone sync "$PB/storage" yos:pb-backups/storage
find "$DIR" -name 'data-*.db.gz' -mtime +14 -delete
# /etc/systemd/system/backup-pocketbase.timer
[Unit]
Description=PocketBase backup
[Timer]
OnCalendar=*-*-* 03:15:00
Persistent=true
[Install]
WantedBy=timers.target
К таймеру нужен одноимённый backup-pocketbase.service с Type=oneshot и ExecStart=/usr/local/bin/backup-pocketbase.sh, затем sudo systemctl enable --now backup-pocketbase.timer. Для Selectel замените эндпоинт на https://s3.ru-1.storage.selcloud.ru. Старые объекты в бакете удобнее чистить правилом жизненного цикла в панели провайдера.
Если PocketBase запущен в Docker, pb_data — это volume или bind mount. Скрипт можно запускать на хосте по пути к bind mount; нюансы с именованными volume и Coolify разобраны в статье бэкап базы в Docker и Coolify.
Восстановление
Из встроенного бэкапа
В Settings → Backups выберите архив и запустите восстановление. PocketBase заменит содержимое pb_data и перезапустит приложение. Перед этим сделайте свежий бэкап текущего состояния: если вы ошиблись архивом, будет куда вернуться. Если PocketBase работает под supervisor или в контейнере с нестандартным запуском, проверьте, что после перезапуска процесс действительно поднялся.
Вручную
sudo systemctl stop pocketbase
# сохранить текущее состояние на всякий случай
sudo mv /opt/pocketbase/pb_data /opt/pocketbase/pb_data.broken-$(date +%F)
# вариант 1: распаковать zip встроенного бэкапа
sudo mkdir /opt/pocketbase/pb_data
sudo unzip /tmp/pb_backup.zip -d /opt/pocketbase/pb_data
# вариант 2: собрать pb_data из своих копий
# gunzip -c data-20260924-0315.db.gz > /opt/pocketbase/pb_data/data.db
# rclone copy yos:pb-backups/storage /opt/pocketbase/pb_data/storage
sqlite3 /opt/pocketbase/pb_data/data.db "PRAGMA integrity_check;"
sudo chown -R pocketbase:pocketbase /opt/pocketbase/pb_data
sudo systemctl start pocketbase
Если подменяете только data.db в существующей папке, удалите рядом старые data.db-wal и data.db-shm — иначе SQLite попытается применить к новой базе журнал от старой. После запуска зайдите в админку, проверьте число записей в ключевых коллекциях и войдите тестовым пользователем. Общий порядок действий и проверок описан в статье как восстановить базу из бэкапа, а регулярный тест восстановления — в материале как проверить, что бэкап рабочий.
Чек-лист перед обновлением PocketBase
До версии 1.0 между релизами бывают несовместимые изменения (например, в 0.23 администраторы стали системной коллекцией _superusers). При старте новая версия применяет свои миграции к data.db, и откатить их назад простой заменой бинарника нельзя.
- Прочитайте changelog всех версий между текущей и целевой.
- Сделайте бэкап
pb_dataи подпишите его версией PocketBase, напримерpre-upgrade-0.x. - Сохраните старый бинарник рядом с новым.
- Проверьте обновление на копии: скопируйте бэкап на тестовую машину, запустите новую версию и пройдите основные сценарии.
- Обновите прод, проверьте логи и ключевые коллекции.
- Если что-то пошло не так: остановите сервис, верните старый бинарник и
pb_dataиз бэкапа шага 2.
Как это сделать в dbsend
dbsend хранит версии data.db как базы SQLite: показывает схему, таблицы и число строк в каждой версии и сравнивает любые две версии (на платных тарифах). Удобно для вопроса «что изменилось в коллекциях после обновления». CLI сам делает консистентную копию через VACUUM INTO, отдельный .backup не нужен:
npm install --global @dbsend/sdk
dbsend login --key sqv_pk_…
dbsend backup /opt/pocketbase/pb_data/data.db -d "$DBSEND_DATABASE_ID" -e sqlite -l "daily"
# перед обновлением
dbsend backup /opt/pocketbase/pb_data/data.db -d "$DBSEND_DATABASE_ID" -e sqlite -l "pre-upgrade"
dbsend log
dbsend pin <snapshotId>
# восстановление: остановите PocketBase, затем
dbsend restore <snapshotId> /opt/pocketbase/pb_data/data.db --yes
dbsend restore проверяет sha256 и PRAGMA integrity_check и с --yes сам убирает устаревшие -wal/-shm рядом с целевым файлом. Если бэкап не пришёл по расписанию, на платных тарифах придёт алерт в Telegram, на email или в webhook. Файлы из storage/ dbsend не инспектирует — для них оставьте S3 или rclone. Подробнее: бэкапы SQLite и документация CLI. Про выбор между репликацией и периодическими версиями — в сравнении Litestream, cron и dbsend. Если PocketBase служит бэкендом для Telegram-бота, посмотрите также бэкап базы Telegram-бота.
Частые вопросы
Достаточно ли встроенных бэкапов PocketBase?
Для небольшого проекта — да, если архивы уходят в S3, а не лежат на том же диске. Если загруженных файлов много или нужна история изменений базы отдельно от файлов, дополните их своей копией data.db и синхронизацией файлов.
Можно ли просто скопировать папку pb_data?
Только при остановленном PocketBase. На работающем сервере копируйте data.db через sqlite3 ... ".backup ..." или используйте встроенный бэкап — простой cp может пропустить данные из -wal.
Нужно ли бэкапить auxiliary.db?
Если там только логи и вы ими не пользуетесь — можно обойтись без неё. Если логи нужны для расследований или аудита, бэкапьте её так же, как data.db.
Миграции в git — это бэкап?
Нет. pb_migrations восстанавливает структуру коллекций, но не записи, пользователей и файлы. Миграции и бэкап данных нужны вместе.
Как бэкапить PocketBase, если файлы хранятся в S3?
Бэкапьте data.db (и при необходимости auxiliary.db), а для бакета с файлами включите версионирование объектов и правила хранения у провайдера. Встроенный бэкап в этом режиме получается компактнее, потому что файлы в архив не попадают.



