- разведка pocketbase-admin-fit ответила замером панели версии 0.39.10: записка в docs/research/pocketbase.md, решение — в ADR - панель показывает файлы и пользователей только своих, поэтому файлы переезжают в её раскладку, а вход идёт через её провайдера OIDC - периметр расширился панелью на /_/ и паролем суперпользователя; закрывает её Authelia на прокси, задачи в беклоге у этого нет
8.3 KiB
PocketBase: что даёт панель администратора
Отвечает на вопрос разведки pocketbase-admin-fit: что панель показывает и
правит по трём частям — записи, пользователи, файлы, — и хватает ли этого, чтобы
держать перевод хранилища в планах.
Как снималось
Версия 0.39.10, выпуск от 2026-07-30 (./pocketbase --version). Смотрел на
пустой базе в каталоге вне репозитория, боевые данные не участвовали. Прогонов
было два:
- готовый бинарник —
pocketbase serve --http=127.0.0.1:8099, суперпользователь заведён командойpocketbase superuser create. Возможности панели снимал её же запросами (/api/collections,/api/logs,/api/backups,/api/crons,/api/settings) и поиском по её собранному коду; - своя сборка, где PocketBase подключён библиотекой к пустому приложению на
Go, — так, как предполагает задача
pocketbase-storage.
Оба прогона удалены вместе с песочницей.
Правка записей — работает целиком
Панель показывает каждую коллекцию таблицей, отбирает записи своим языком фильтров, сортирует, создаёт, правит и удаляет их по одной. Сверх таблицы в ней есть выгрузка списка в CSV, журнал запросов с временем ответа и кодом, резервные копии с загрузкой и восстановлением, список заданий планировщика.
Групповой операции над отмеченными записями в панели нет: удаление идёт по одной. Проверял поиском по её коду — строк вида «удалить отмеченное» в нём не нашлось, тогда как «Export as CSV» и «Download JSON» нашлись.
Пользователи — только те, кого туда положат
Панель показывает свою коллекцию пользователей и ничего больше. Отсюда следствие
для целевого входа: пользователи Authelia в панели не появятся, если вход
делает само приложение. Пустая база заводит шесть коллекций, из них одна
пользовательская (users) и пять служебных, включая _externalAuths — связь
записи с внешним провайдером.
Второй путь есть, и он работает: вход можно отдать самой PocketBase. У
пользовательской коллекции настраивается провайдер oidc с произвольными
адресами; я включил его на адреса вида https://auth.example.com/api/oidc/...,
и клиент немедленно стал получать провайдера в списке способов входа. Тогда
учётные записи заводятся сами, и панель их видит.
В саму панель Authelia не пускает. Вход суперпользователя — своя почта и свой пароль:
- включить
oidcу коллекции суперпользователей не удалось: запрос принимается, но возвращает коллекцию с выключеннымoauth2; - включить второй фактор у неё же не удалось тоже — ответ
403.
Ограничить панель списком адресов можно: настройка superuserIPs принимает
адреса и подсети. Ею же можно запереть себя — после того как я поставил туда
чужой адрес, все запросы суперпользователя, включая запрос на сброс настройки,
стали отвечать 403. Команды сброса в наборе нет: он состоит из migrate,
superuser, update и serve.
Файлы — только свои
Файл живёт полем записи, и раскладку на диске выбирает PocketBase:
pb_data/storage/<коллекция>/<запись>/<имя>_<10 случайных символов>.ogg
pb_data/storage/<коллекция>/<запись>/<имя>_<10 случайных символов>.ogg.attrs
Проверено загрузкой файла в 200 КБ: имя sample.ogg превратилось в
sample_uztrv6wvz3.ogg, рядом лёг файл атрибутов.
Сегодняшняя раскладка data/files с именами-UUID панели не видна. Путь строкой
она покажет строкой — прослушать и скачать запись по ней нельзя. Способа сослаться
на файл, уже лежащий на диске мимо её каталога, нет.
Поле помечается защищённым, и тогда файл не отдаётся по прямой ссылке: без токена
ответ 404, с выданным файловым токеном — 200.
Резервные копии накрывают ровно её каталог. Файлы, оставленные снаружи, в них не попадут — то есть панель и встроенное резервное копирование покупаются одной и той же ценой.
Побочное: CGO уходит
Библиотечная сборка встала при CGO_ENABLED=0 — PocketBase ходит в SQLite через
modernc.org/sqlite, а не через mattn/go-sqlite3. Требование CGO записано
сегодня свойством стека в ../../CLAUDE.md, и перевод его снимает.
Бинарник пробника — 33 954 634 байта против 43 498 904 у сегодняшнего приложения
(go build без флагов). Числа не сравнимы напрямую: в пробнике нет ни бота,
ни клиента SpeechKit, ни клиента Object Storage. Что даст сборка после перевода,
не замерялось.
Панель отдаётся по адресу /_/ того же порта, что и остальное приложение, — и в
библиотечной сборке тоже: пустое приложение с одним своим обработчиком отвечало
на /_/ кодом 200.
Что отвергнуто и почему
- Держать файлы на диске как сейчас, а в базе — путь строкой. Отвергнуто: панель тогда не даёт по файлам ничего, и встроенные копии их не накрывают. Довод, ради которого перевод затевался, пропадает целиком.
- Оставить вход у приложения, а PocketBase взять только хранилищем. Отвергнуто: пользователей панель в этом случае не показывает вовсе, и одна из трёх частей вопроса остаётся без ответа навсегда, а не до какой-то задачи.
- Отказаться от перевода. Отвергнуто человеком на чекпоинте 2026-08-11: вместе с панелью отказ выбрасывал бы уход CGO и встроенное резервное копирование, которых у сервиса-архива нет никаких.