MAATRIX / Блог / linkding: зачем держать закладки на сервере, если есть браузер

linkding: зачем держать закладки на сервере, если есть браузер

MAATRIX

У браузера есть закладки, у закладок есть синхронизация через аккаунт — казалось бы, вопрос закрыт ещё до того, как его успели задать. Но у кого-то накопились сотни ссылок, разбросанных по трём браузерам и двум аккаунтам, у кого-то — команда, где каждый хранит нужные ссылки у себя и теряет их при смене компьютера, у кого-то — привычка сохранять статью «почитать потом», а потом обнаруживать, что страница удалена, а в закладке остался мёртвый URL без единого слова о том, что там было. linkding — self-hosted менеджер закладок, который решает именно эти три проблемы: общий доступ, поиск по содержимому, а не только по названию, и архивный снимок страницы на случай, если оригинал исчезнет. Вопрос не в том, хорош ли инструмент — вопрос в том, для какой именно из этих проблем он вам действительно нужен, а для какой это лишняя строчка в списке того, что придётся администрировать.

Что предлагает linkding и чем это отличается от Ctrl+D

linkding — открытый проект на Python/Django, который разворачивается одним Docker-контейнером и по интерфейсу похож на минималистичный веб-клиент для закладок: строка добавления ссылки, список с тегами, поиск сверху. По функциональности он ближе не к «папкам избранного» браузера, а к личной поисковой системе по сохранённым страницам:

  • Плоские теги вместо иерархии папок. Одной закладке можно присвоить сразу несколько тегов (docker, network, to-read), и она найдётся по любому из них — не нужно заранее решать, в какую единственную папку её положить.
  • Полнотекстовый поиск, который смотрит не только в заголовок и URL, но и в описание закладки, а при включённых снапшотах — и в извлечённый текст самой страницы.
  • Архивные снапшоты — при сохранении закладки linkding может сразу забрать копию страницы (текст и, опционально, полный HTML), чтобы через полгода, когда оригинал переедет или удалится, у вас осталась не мёртвая ссылка, а рабочая копия содержимого.
  • REST API с токеном — можно добавлять, искать и удалять закладки скриптом, ботом, расширением или мобильным шорткатом, не открывая веб-интерфейс.
  • Импорт и экспорт в формате Netscape Bookmark File — том самом стандартном HTML-файле, который отдаёт «Экспорт закладок» в любом браузере, так что миграция в обе стороны не требует ручного переноса.
  • Браузерное расширение для Firefox и Chrome — кнопка «Сохранить» с тегами прямо в тулбаре, без захода на сервер руками.

Ключевое отличие от синхронизации закладок в браузере — не красота интерфейса, а то, что данные и логика поиска живут на вашем сервере, доступны по API и не привязаны к конкретному браузерному аккаунту конкретного человека.

Для кого браузерных закладок реально не хватает

Есть конкретные сценарии, где синхронизация через аккаунт браузера объективно не решает задачу:

Команде нужен общий каталог ссылок. Если пять человек независимо сохраняют полезные ссылки на документацию поставщиков, внутренние регламенты, инструменты — и делают это каждый в своём браузере, реальный результат: у каждого свой неполный список, и найти нужную ссылку можно только спросив в чате «а у кого есть та статья про...». Общий инстанс linkding с несколькими учётками и расшаренными закладками закрывает это одним местом, куда идут все и откуда все ищут.

Нужен поиск по содержимому, а не только по названию сохранённой страницы. Если вы через месяц помните не заголовок статьи, а фразу оттуда или конкретный термин — заголовки в браузерных закладках вам не помогут: там ищет только по названию и, иногда, по URL. Полнотекстовый поиск по снапшотам решает именно это — ищете «rate limiting nginx», находите закладку, даже если в заголовке этого не было.

Важна защита от link rot. Ссылки на важные для работы материалы — документацию API, регуляторные требования, чужие технические статьи — со временем протухают: страницы переезжают, авторы удаляют посты, домены истекают. Архивный снапшот при сохранении означает, что даже мёртвая ссылка оставляет вам рабочую копию текста.

Нужна автоматизация через API. Если вы хотите, чтобы ссылки из Telegram-канала, RSS-подборки или скрипта парсинга сами попадали в базу с тегами — браузерным закладкам вы такое не поручите, а linkding отдаёт для этого готовый REST API.

Важна независимость от экосистемы конкретного вендора. Закладки в аккаунте Google или Microsoft — данные внутри чужой инфраструктуры, подчинённые её политикам и доступности. Для кого-то это не проблема, для кого-то — принципиальный пункт, особенно если остальная инфраструктура уже переехала на свои серверы.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Кому это лишняя инфраструктура — честно

А теперь обратная сторона, потому что не каждому из перечисленного нужен собственный сервер.

Один человек, один-два устройства, обычная синхронизация уже работает. Если вы сохраняете закладки эпизодически и находите их потом по названию — штатной синхронизации Chrome, Firefox или Safari через аккаунт достаточно, она бесплатна, ничего не нужно администрировать, и она уже настроена.

Небольшое количество ссылок, которые легко держать в голове или в двух-трёх папках. Полнотекстовый поиск и теги оправдывают себя при сотнях и тысячах сохранённых страниц. Если у вас их пара десятков, выгода от отдельного сервиса не покрывает затраты времени на его настройку и поддержку.

Нет человека, готового администрировать ещё один Docker-сервис. linkding сам по себе несложен в обслуживании, но это всё равно контейнер, который нужно обновлять, бэкапить и защищать от публичного доступа. Если в команде и так не хватает рук на инфраструктуру, добавление шестого self-hosted сервиса ради закладок — сомнительный приоритет. Общая логика такого расчёта разобрана в статье про экономику self-hosted решений — что действительно выгодно держать у себя: предельные затраты на новый сервис резко падают, если инфраструктура под другие задачи уже есть и уже оплачена, и растут, если это первый и единственный self-hosted сервис в компании.

Цель — не каталог ссылок, а чтение статей целиком. Если вам нужно не «сохранить ссылку с тегом», а «сохранить статью целиком, чтобы прочитать её позже без рекламы и без риска, что она исчезнет», ближе по назначению будет read-it-later сервис вроде Wallabag — там акцент на полном тексте статьи и режиме чтения, а не на каталогизации большого числа ссылок. Установка описана в статье про развёртывание Wallabag на Ubuntu 24.04. Это близкие, но не взаимозаменяемые инструменты: linkding — про каталог и поиск по многим ссылкам, Wallabag — про вдумчивое чтение немногих статей целиком.

Установка: Docker Compose и первый запуск

Официальный образ — sissbruecker/linkding, разворачивается одним контейнером с базой SQLite по умолчанию (для команды в несколько человек её обычно достаточно, PostgreSQL подключается отдельно, если нужен больший масштаб или свои требования к бэкапам базы). Минимальный docker-compose.yml:

services:
  linkding:
    image: sissbruecker/linkding:latest
    container_name: linkding
    restart: unless-stopped
    ports:
      - "127.0.0.1:9090:9090"
    volumes:
      - linkding_data:/etc/linkding/data
    environment:
      - LD_SUPERUSER_NAME=admin
      - LD_SUPERUSER_PASSWORD=замените-на-случайный-пароль
      - LD_SERVER_PORT=9090
volumes:
  linkding_data:

Порт намеренно привязан к 127.0.0.1, а не наружу — снаружи закладки закрываем через reverse proxy с TLS, а не голым портом. Поднимаем и проверяем:

docker compose up -d
docker compose logs -f linkding

Пример конфига Caddy для публикации с автоматическим сертификатом:

links.example.com {
    reverse_proxy 127.0.0.1:9090
}

Если сервис нужен только команде и не должен быть виден снаружи вообще, логичнее не публиковать его в интернет даже за паролем, а держать в приватной сети — том же WireGuard, что и остальные внутренние инструменты. Типовая схема такой сети для распределённой команды разобрана в статье про VPN для удалённой команды, эта же логика подходит и для linkding, если закладки — внутренний рабочий инструмент, а не публичный дашборд.

После первого запуска заходим под admin, создаём остальным участникам команды учётки через Django admin (/admin/) — у каждого будет своя область закладок, а нужные видны всем через флаг «shared», о котором ниже.

Теги, поиск и снапшоты страниц на практике

Теги вместо папок. У linkding нет вложенных папок — только плоские теги, и это осознанное решение: одна ссылка на документацию Docker-сети может относиться одновременно к docker, network и reference, и папка заставила бы выбрать что-то одно. При вводе тегов работает автодополнение по уже существующим, что снижает риск развести nginx и Nginx как разные теги. Массовое перетегирование делается через выбор нескольких закладок в списке и групповое действие — полезно, когда нужно навести порядок в накопившемся архиве.

Поиск. По умолчанию поиск смотрит заголовок, описание, URL и теги. Если включены снапшоты, поиск может искать и по извлечённому тексту самой страницы — это и есть отличие от закладок браузера: вы находите страницу не потому что помните, как она называлась, а потому что помните, что на ней было написано.

Снапшоты и архивирование. Функция снапшотов включается отдельно и при сохранении новой закладки запускает рендеринг страницы headless-браузером внутри контейнера, чтобы сохранить рабочую копию содержимого. Это полезная страховка от link rot, но у неё есть цена:

  • рендеринг страницы через headless-браузер заметно тяжелее, чем просто сохранение URL — на слабом VPS с 1 vCPU это может ощутимо тормозить массовое добавление закладок;
  • снапшоты занимают место на диске, и при активном использовании база разрастается быстрее, чем кажется на старте — стоит заранее прикинуть объём диска с запасом, а не расширять том в панике через полгода;
  • снапшоты нужно бэкапить вместе с базой, а не только базу — иначе после аварии у вас останутся ссылки, но не архивные копии, ради которых всё затевалось.

Для небольшой команды с умеренным темпом добавления закладок (десятки в неделю, а не тысячи) обычно достаточно младшего VPS с 1-2 vCPU и 2 ГБ RAM, если снапшоты включены, и хватит меньшего объёма, если снапшоты отключены и нужен только каталог со ссылками и поиском по метаданным.

Общий доступ команды и API как рабочий инструмент, а не тупиковая ветка

Расшаренные закладки. Каждый пользователь в linkding по умолчанию видит только свои закладки, но при сохранении можно отметить закладку как общую — тогда она попадает в объединённый список, видимый всей команде, а личные заметки и черновые ссылки остаются приватными. Это удобный баланс между «у каждого своё» и «всё видно всем»: не нужно заранее решать на входе, какая ссылка достойна общего каталога, а какая нет — можно расшарить в любой момент.

REST API. Токен для API создаётся в настройках профиля, дальше добавление закладки — обычный POST-запрос:

curl -X POST https://links.example.com/api/bookmarks/ \
  -H "Authorization: Token ВАШ_ТОКЕН" \
  -H "Content-Type: application/json" \
  -d '{
        "url": "https://example.com/статья",
        "tag_names": ["reference", "to-read"],
        "title": "Заголовок статьи"
      }'

На этом API строятся практичные автоматизации:

  • бот в Telegram, который добавляет в linkding ссылку из пересланного сообщения по команде;
  • скрипт, который раз в день выгружает отмеченные звёздочкой материалы из RSS-читалки и складывает их в linkding с тегом источника;
  • интеграция с мобильными шорткатами (iOS Shortcuts / Android Tasker) — «поделиться» из любого приложения сразу с нужным тегом;
  • скрипт очистки — периодическая проверка, что сохранённые URL всё ещё отвечают 200-м кодом, и пометка протухших тегом dead-link для ручной проверки архивной копии.

Именно это отличает linkding от закладок браузера сильнее всего: закладка в браузере — тупиковая ветка, которую видит только сам браузер. Закладка в linkding — запись в базе с API, к которой может обратиться что угодно ещё в вашей инфраструктуре.

Бэкап и обслуживание

Данные лежат в примонтированном томе linkding_data — база (SQLite-файл, если не подключали Postgres) и снапшоты, если они включены. Простой скрипт для регулярного дампа:

#!/usr/bin/env bash
DATE=$(date +%Y-%m-%d)
docker compose exec -T linkding cp /etc/linkding/data/db.sqlite3 /etc/linkding/data/backup-${DATE}.sqlite3
docker run --rm -v linkding_linkding_data:/data -v $(pwd)/backups:/backup alpine \
  tar czf /backup/linkding-${DATE}.tar.gz -C /data .

Запускать по cron ежедневно, хранить копии за пределами того же сервера — тот же принцип, что и для любого self-hosted сервиса с единственной базой без репликации: если диск с единственной копией данных откажет, восстанавливать без внешнего бэкапа будет нечего. Обновление образа — стандартное docker compose pull && docker compose up -d, миграции базы linkding применяет сам при старте контейнера, ручного вмешательства обычно не требуется.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

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

linkding поддерживает несколько пользователей с реальным разделением доступа?

Да, учётки создаются через Django admin, у каждого пользователя свои приватные закладки, а расшаренные становятся видны всей команде через отдельный флаг у конкретной закладки — это не полноценные роли и права, а простая модель «приватное / общее», которой для небольшой команды обычно достаточно.

Нужен ли для linkding отдельный мощный сервер?

Нет, без снапшотов сервис лёгкий и хватит младшего VPS. Со включёнными снапшотами закладывайте больше ресурсов на CPU (рендеринг страниц) и на диск (хранение архивных копий) — конкретные цифры зависят от темпа добавления закладок и размера сохраняемых страниц.

Чем это лучше Raindrop.io или похожего облачного сервиса закладок?

Данные и логика поиска остаются на вашем сервере, доступ по API без ограничений тарифного плана, нет зависимости от того, что будет с облачным сервисом через несколько лет. Минус обратный: обслуживание, обновления и бэкапы — тоже ваша задача, а не задача вендора.

Можно ли перенести существующие закладки из браузера?

Да, через штатный экспорт браузера в файл формата Netscape Bookmark File (HTML) и последующий импорт этого файла в linkding — формат стандартный, конвертировать вручную не требуется.

А если нужно и общий каталог ссылок, и полный текст статей для чтения?

Ничто не мешает держать оба инструмента рядом на одном сервере: linkding — для каталога, тегов и быстрого поиска по большому числу ссылок, Wallabag — для вдумчивого чтения отдельных статей целиком в читаемом виде. Многие self-hosted пользователи так и делают, это не взаимоисключающие сервисы.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →