PocketBase: что это такое и как начать работать

Обновлено:

PocketBase — открытый бэкенд, который поставляется как один исполняемый файл. Внутри: база данных SQLite, REST API, аутентификация пользователей, файловое хранилище, realtime-подписки и административная панель. Скачали, запустили — и через минуту у вас работающий API. PocketBase часто выбирают для MVP, внутренних инструментов и небольших продуктов, где Supabase избыточен, а писать бэкенд с нуля долго.

Что такое PocketBase и зачем он нужен

PocketBase — open-source проект на Go. Ключевые свойства:

  • один бинарный файл без внешних зависимостей;
  • встроенная SQLite (подробнее о самой СУБД — в статье что такое SQLite);
  • REST API, который генерируется по схеме коллекций;
  • встроенная аутентификация: email/пароль, OAuth2, OTP по email;
  • административная панель по адресу /_/;
  • расширение логики на JavaScript (pb_hooks) или на Go, если использовать PocketBase как библиотеку.

По функциям PocketBase близок к Supabase, но разворачивается без Docker, PostgreSQL и Kubernetes. Важно помнить: проект ещё не достиг версии 1.0, и авторы прямо предупреждают, что между версиями возможны несовместимые изменения. Актуальную версию смотрите на странице GitHub Releases, а перед обновлением читайте changelog.

Установка PocketBase

Скачать и запустить локально

# Linux / macOS — подставьте актуальную версию с GitHub Releases
PB_VERSION=0.xx.x
wget https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/pocketbase_${PB_VERSION}_linux_amd64.zip
unzip pocketbase_${PB_VERSION}_linux_amd64.zip
chmod +x pocketbase
./pocketbase serve

На Windows скачайте архив pocketbase_<версия>_windows_amd64.zip, распакуйте и выполните pocketbase.exe serve.

После запуска в терминале появятся адреса:

Server started at http://127.0.0.1:8090
├─ REST API: http://127.0.0.1:8090/api/
└─ Dashboard: http://127.0.0.1:8090/_/

При первом запуске PocketBase выведет ссылку для создания аккаунта superuser. Откройте её — и можно работать.

Что появится рядом с бинарником:

./
├── pocketbase          # исполняемый файл
├── pb_data/            # данные: БД, загруженные файлы
│   ├── data.db         # основная SQLite-база (коллекции, записи, настройки)
│   ├── auxiliary.db    # вспомогательная база (логи запросов)
│   └── storage/        # загруженные файлы
└── pb_migrations/      # миграции (если вы их используете)

Запуск через Docker

# Dockerfile
FROM alpine:latest

ARG PB_VERSION=0.xx.x

RUN apk add --no-cache unzip ca-certificates && \
    wget https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/pocketbase_${PB_VERSION}_linux_amd64.zip && \
    unzip pocketbase_${PB_VERSION}_linux_amd64.zip && \
    rm pocketbase_${PB_VERSION}_linux_amd64.zip

EXPOSE 8090

CMD ["/pocketbase", "serve", "--http=0.0.0.0:8090"]
# docker-compose.yml
services:
  pocketbase:
    build: .
    ports:
      - "8090:8090"
    volumes:
      - ./pb_data:/pb_data
      - ./pb_migrations:/pb_migrations
    restart: unless-stopped

Главное — вынести pb_data в volume: всё состояние приложения живёт там. Как бэкапить такие тома, разобрано в статье про бэкап БД в Docker и Coolify.

Создание коллекций

Коллекции в PocketBase — это таблицы с автоматически сгенерированным API. Создаются через панель или через API.

Создание коллекции через панель

  1. Откройте http://localhost:8090/_/.
  2. Нажмите «New collection».
  3. Укажите название, например posts.
  4. Добавьте поля:
    • title — Text, обязательное;
    • content — Editor (rich text);
    • author — Relation → users;
    • cover_image — File, максимум 1 файл;
    • tags — Select с множественным выбором;
    • published — Bool.
  5. Сохраните.

PocketBase сразу создаст REST-эндпоинты:

GET    /api/collections/posts/records      — список записей
POST   /api/collections/posts/records      — создать запись
GET    /api/collections/posts/records/:id  — одна запись
PATCH  /api/collections/posts/records/:id  — обновить
DELETE /api/collections/posts/records/:id  — удалить

Основные типы полей

| Тип | Описание | Пример | |---|---|---| | Text | Строка | Заголовок, имя | | Number | Число | Цена, количество | | Bool | Да/нет | Опубликован | | Email | Email с валидацией | user@example.com | | URL | URL с валидацией | https://example.com | | DateTime | Дата и время | 2026-05-01 12:00 | | Autodate | Автоматические created/updated | Время создания | | Select | Выбор из вариантов | status: draft/published | | File | Файл или изображение | Обложка, аватар | | Relation | Связь с другой коллекцией | author → users | | Editor | Rich text (HTML) | Текст статьи | | JSON | Произвольный JSON | Настройки, метаданные |

Аутентификация в PocketBase

Коллекция users

При первом запуске PocketBase создаёт auth-коллекцию users. Поддерживаются:

  • email + пароль;
  • OAuth2 (Google, GitHub, Apple, Discord, GitLab и другие провайдеры, а также универсальный OpenID Connect);
  • одноразовые коды (OTP) по email.

Регистрация и вход через JavaScript SDK

import PocketBase from 'pocketbase';

const pb = new PocketBase('http://localhost:8090');

// Регистрация
await pb.collection('users').create({
    email: 'alex@example.com',
    password: 'securepassword123',
    passwordConfirm: 'securepassword123',
    name: 'Алексей'
});

// Вход по email и паролю
await pb.collection('users').authWithPassword(
    'alex@example.com',
    'securepassword123'
);

// pb.authStore.record — текущий пользователь
// pb.authStore.token — токен, SDK сам добавляет его в заголовки
console.log(pb.authStore.record);

// Вход через OAuth2
await pb.collection('users').authWithOAuth2({ provider: 'google' });

// Обновление профиля
await pb.collection('users').update(pb.authStore.record.id, {
    name: 'Алексей Иванов',
    avatar: fileObject // объект File
});

// Выход
pb.authStore.clear();

В старых версиях SDK текущий пользователь лежал в pb.authStore.model; в актуальных — в pb.authStore.record.

API Rules — управление доступом

Доступ к записям задаётся API Rules — выражениями-фильтрами для операций list, view, create, update и delete.

# Список постов: публичный
listRule: ""

# Просмотр: опубликованные — всем, черновики — автору
viewRule: published = true || author = @request.auth.id

# Создание: только авторизованные
createRule: @request.auth.id != ""

# Обновление и удаление: только автор
updateRule: author = @request.auth.id
deleteRule: author = @request.auth.id

@request.auth.id — ID текущего пользователя. По смыслу это похоже на Row-Level Security в PostgreSQL, но настраивается в панели без SQL. Синтаксис, операторы и типовые ошибки подробно разобраны в статье API Rules в PocketBase.

Работа с файлами

// Создание записи с файлом
const formData = new FormData();
formData.append('title', 'Моя статья');
formData.append('cover_image', fileInput.files[0]);

const record = await pb.collection('posts').create(formData);

// URL файла
const imageUrl = pb.files.getURL(record, record.cover_image);
// http://localhost:8090/api/files/posts/RECORD_ID/IMAGE_NAME.jpg

// URL миниатюры 100x100 (размеры миниатюр задаются в настройках поля)
const thumbUrl = pb.files.getURL(record, record.cover_image, { thumb: '100x100' });

По умолчанию файлы хранятся в pb_data/storage/. В настройках можно переключить хранение файлов на S3-совместимое хранилище.

Realtime-подписки

Realtime в PocketBase работает через Server-Sent Events:

// Подписка на все изменения коллекции
pb.collection('messages').subscribe('*', (e) => {
    console.log(e.action); // "create" | "update" | "delete"
    console.log(e.record);

    if (e.action === 'create') {
        addMessageToUI(e.record);
    }
});

// Подписка на одну запись
pb.collection('orders').subscribe('ORDER_ID', (e) => {
    updateOrderStatus(e.record.status);
});

// Отписка
pb.collection('messages').unsubscribe();

JavaScript SDK: работа с коллекциями

import PocketBase from 'pocketbase';
const pb = new PocketBase('https://your-pocketbase.com');

// Список с фильтром, сортировкой и пагинацией
const posts = await pb.collection('posts').getList(1, 20, {
    filter: 'published = true && created >= "2026-01-01"',
    sort: '-created',
    expand: 'author',
    fields: 'id,title,created,expand.author.name'
});
// posts.items, posts.totalItems, posts.totalPages

// Все записи без пагинации
const allTags = await pb.collection('tags').getFullList({ sort: 'name' });

// Одна запись
const post = await pb.collection('posts').getOne('RECORD_ID', {
    expand: 'author'
});

// Первая запись по фильтру
const latestPost = await pb.collection('posts').getFirstListItem(
    'published = true',
    { sort: '-created' }
);

// Создание, обновление, удаление
const newPost = await pb.collection('posts').create({
    title: 'Новая статья',
    content: '<p>Содержимое</p>',
    author: pb.authStore.record.id,
    published: false
});
await pb.collection('posts').update('RECORD_ID', { published: true });
await pb.collection('posts').delete('RECORD_ID');

Расширение PocketBase своей логикой

Хуки и свои маршруты можно писать на JavaScript (файлы *.pb.js в pb_hooks/) или на Go.

// pb_hooks/main.pb.js

// Перед созданием записи — подставить автора
onRecordCreateRequest((e) => {
    if (e.auth) {
        e.record.set('author', e.auth.id);
    }
    e.next();
}, 'posts');

// После успешного создания — письмо автору
onRecordAfterCreateSuccess((e) => {
    e.next();

    const author = $app.findRecordById('users', e.record.getString('author'));
    const message = new MailerMessage({
        from: {
            address: $app.settings().meta.senderAddress,
            name: $app.settings().meta.senderName,
        },
        to: [{ address: author.email() }],
        subject: 'Статья создана',
        html: `<p>Ваша статья "${e.record.getString('title')}" создана.</p>`,
    });
    $app.newMailClient().send(message);
}, 'posts');

// Свой API-маршрут
routerAdd('POST', '/api/custom/send-notification', (e) => {
    const data = e.requestInfo().body;
    // ваша логика
    return e.json(200, { status: 'sent' });
});

Деплой PocketBase на VPS

Ubuntu/Debian + systemd + Nginx

# 1. Скачать PocketBase
PB_VERSION=0.xx.x
wget https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/pocketbase_${PB_VERSION}_linux_amd64.zip
unzip pocketbase_${PB_VERSION}_linux_amd64.zip -d /opt/pocketbase
chmod +x /opt/pocketbase/pocketbase
chown -R www-data:www-data /opt/pocketbase

# 2. systemd-сервис
cat > /etc/systemd/system/pocketbase.service << 'EOF'
[Unit]
Description=PocketBase
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/pocketbase
ExecStart=/opt/pocketbase/pocketbase serve --http=127.0.0.1:8090
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now pocketbase

# 3. Nginx как реверс-прокси (настройки под SSE для realtime)
cat > /etc/nginx/sites-available/pocketbase << 'EOF'
server {
    listen 80;
    server_name your-domain.com;
    client_max_body_size 10M;

    location / {
        proxy_set_header Connection '';
        proxy_http_version 1.1;
        proxy_read_timeout 360s;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://127.0.0.1:8090;
    }
}
EOF

ln -s /etc/nginx/sites-available/pocketbase /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

# 4. TLS через Certbot
certbot --nginx -d your-domain.com

Деплой через Coolify

Если на VPS уже стоит Coolify, PocketBase можно поднять из Dockerfile выше (или из готового шаблона сервиса, если он есть в вашем каталоге Coolify). Обязательные пункты: постоянный volume для /pb_data, порт 8090 и домен с TLS.

Бэкап PocketBase

Всё состояние PocketBase — в каталоге pb_data: база data.db и загруженные файлы в storage/. Потеряли каталог — потеряли пользователей, записи и настройки.

Встроенный механизм: в панели (Settings → Backups) PocketBase умеет создавать zip-архив pb_data вручную или по cron-расписанию и складывать его локально в pb_data/backups или в S3. Это хорошая база, но архивы на том же сервере не спасут при потере диска, а проверять их содержимое придётся вручную.

Если копируете базу сами, не делайте cp data.db на работающем сервере: PocketBase использует WAL-режим, и часть транзакций может лежать в файле data.db-wal. Используйте sqlite3 .backup или VACUUM INTO — подробности в статье как сделать бэкап SQLite без повреждения.

Пример выгрузки в бэкапы SQLite в dbsend:

npm install --global @dbsend/sdk
dbsend login --key sqv_pk_...

# База: CLI сам делает консистентную копию SQLite перед загрузкой
dbsend backup /opt/pocketbase/pb_data/data.db -d "$DBSEND_DATABASE_ID" -e sqlite -l nightly

# Загруженные файлы — отдельным архивом как generic_file
tar -czf /tmp/pb_storage.tar.gz -C /opt/pocketbase/pb_data storage
dbsend backup /tmp/pb_storage.tar.gz -d "$DBSEND_FILES_ID" -e generic_file

Каждая загрузка становится версией базы; для SQLite dbsend показывает таблицы и число строк и умеет сравнивать версии. Пошаговая схема с cron, ротацией и восстановлением — в статье бэкап PocketBase.

PocketBase vs Supabase vs Firebase

| Параметр | PocketBase | Supabase | Firebase | |---|---|---|---| | База данных | SQLite | PostgreSQL | Firestore (NoSQL) | | Деплой | Один файл | Облако или Docker | Только облако | | Self-hosted | Просто | Сложнее (много сервисов) | Нет | | Масштабирование | Вертикальное, один сервер | Высокое | Высокое | | Цена | Бесплатно при self-host, платите за VPS | Есть бесплатный облачный тариф | Есть бесплатный тариф | | Аутентификация | Встроенная | Встроенная | Встроенная | | Realtime | SSE | WebSocket | Нативный | | Официальные SDK | JS, Dart | JS, Dart, Python, Swift и др. | iOS, Android, Web и др. | | Данные в России | Да, при self-host на российском VPS | Только self-host | Нет |

Выбирайте PocketBase, если:

  • делаете MVP или прототип и нужно запуститься быстро;
  • хватает одного сервера и нагрузка предсказуема;
  • хотите self-hosted бэкенд на недорогом VPS;
  • пишете код с AI-ассистентом: по PocketBase много документации и примеров.

Выбирайте Supabase, если:

  • нужен полноценный PostgreSQL и SQL;
  • команда знает PostgreSQL и RLS;
  • ожидается рост, который один сервер не вытянет.

Выбирайте Firebase, если:

  • делаете мобильное приложение и нужны зрелые нативные SDK;
  • важна интеграция с Google Analytics и Crashlytics.

Ограничения PocketBase

SQLite не масштабируется горизонтально. Один процесс, один сервер, один писатель в каждый момент. Для большинства небольших проектов этого хватает, но при росте нагрузки на запись или требовании нескольких серверов придётся переходить на PostgreSQL.

Нет полноценной очереди задач. Есть встроенный планировщик (cronAdd в хуках), но для тяжёлых фоновых задач нужна внешняя очередь.

API ещё не v1.0. Перед каждым обновлением читайте changelog и делайте бэкап pb_data.

JavaScript в хуках — не Node.js. Встроенный движок goja поддерживает ES5 и большую часть ES6, но npm-пакеты, завязанные на Node API, работать не будут. Для сложной логики используйте Go.

Полнотекстовый поиск по русскому тексту ограничен. Фильтр ~ — это LIKE, без морфологии. Для серьёзного поиска подключают Meilisearch или аналог.

Частые вопросы

Подходит ли PocketBase для production?

Да, для многих проектов: внутренние инструменты, MVP, небольшие SaaS. Но учитывайте, что до v1.0 возможны несовместимые изменения, а масштабирование ограничено одним сервером. Для систем с высокой нагрузкой на запись или требованием отказоустойчивости на нескольких узлах лучше PostgreSQL.

Как обновлять PocketBase без потери данных?

Сделайте бэкап pb_data, затем замените бинарник новой версией (для готового бинарника есть команда ./pocketbase update). Данные в pb_data/ сохраняются, нужные системные миграции PocketBase применит при старте. Если обновление пошло не так, вы откатываетесь на старый бинарник и копию pb_data.

Можно ли использовать PocketBase как Go-фреймворк?

Да. PocketBase подключается к Go-проекту как библиотека: вы добавляете свои маршруты, хуки и логику и собираете один бинарник.

Как подключить PocketBase к React или Next.js?

Установите SDK npm install pocketbase и создайте клиент в отдельном модуле. В Next.js для серверных компонентов создавайте новый экземпляр на каждый запрос и восстанавливайте сессию из cookie, а клиентскую авторизацию оставьте в client components. Пример — в статье PocketBase как бэкенд.

Какой максимальный размер файла?

Он задаётся в настройках поля File (параметр максимального размера). Для больших файлов включите S3-совместимое хранилище в настройках PocketBase.

Как настроить автоматический бэкап PocketBase?

Три варианта: встроенные бэкапы в панели (Settings → Backups, локально или в S3); свой cron-скрипт с sqlite3 .backup и выгрузкой в S3; загрузка копий в dbsend с версиями, сравнением и алертами, если бэкап не пришёл по расписанию. В любом варианте периодически проверяйте восстановление на тестовой машине.