MAATRIX / Блог / Wallabag в Docker Compose: готовый файл

Wallabag в Docker Compose: готовый файл

MAATRIX

Летом 2025-го Mozilla закрыла Pocket — и все, кто годами копил там ссылки «почитать вечером», в один день остались без сервиса. Instapaper и Readwise Reader работают, но это снова чья-то инфраструктура и снова подписка. Wallabag решает вопрос радикально: один контейнер на вашем VPS, ваша база, ваши статьи — и никто не закроет сервис поверх вас. Ниже — рабочий docker-compose.yml, который поднимается за несколько минут, плюс домен с SSL, импорт старых закладок и бэкап.

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

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

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

Зачем self-hosted read-it-later и чем Wallabag отличается от альтернатив

Идея read-it-later сервиса простая: увидели интересную статью — сохранили одним кликом, а не читаете сразу и не держите вкладку открытой неделю. Сервис вытаскивает из страницы чистый текст без рекламы, баннеров подписки и меню сайта, сохраняет офлайн-копию и даёт спокойно дочитать позже — с телефона, планшета или в браузере.

Из живых вариантов на рынке остались:

  • Instapaper — работает, но бесплатный тариф режет число сохранённых highlight'ов, за полный набор функций нужна подписка;
  • Readwise Reader — платный с самого начала, ориентирован скорее на заметки и подсветки, чем на простое «сохранить и прочитать»;
  • Omnivore — был open-source и self-hosted, но проект закрылся в 2024-м, что лишний раз подтверждает: даже open-source сервис можно закрыть, если исчезнет команда.

Wallabag — единственный из активно поддерживаемых read-it-later с полноценным self-hosted вариантом:

  • Полнотекстовое извлечение — забирает основной контент страницы, отбрасывая вёрстку сайта, похоже на встроенный Reader Mode браузера, но постоянно и с архивом;
  • Теги, избранное, полнотекстовый поиск по всем сохранённым статьям;
  • RSS-экспорт — каждый тег и папка «непрочитанное» отдаются отдельным RSS-фидом, это удобно стыкуется с RSS-агрегатором вроде FreshRSS, если он у вас уже крутится на том же сервере;
  • Открытый REST API с OAuth2 — под него уже есть официальные расширения браузера, мобильные приложения и десятки сторонних интеграций.

Честно про минус: разбор контента у Wallabag не идеален — пейволлы, сайты с тяжёлым JS-рендерингом и нестандартная вёрстка иногда сохраняются без текста, только заголовком. Это ограничение самого экстрактора контента, а не конфигурации, и с этим сталкиваются все read-it-later сервисы без исключения, включая закрытые.

Готовый docker-compose.yml

Официальный образ wallabag/wallabag умеет работать с SQLite, MySQL/MariaDB и PostgreSQL. Для личного архива на несколько сотен статей SQLite — самый простой путь, без отдельного контейнера базы:

services:
  wallabag:
    image: wallabag/wallabag
    container_name: wallabag
    restart: unless-stopped
    ports:
      - "8080:80"
    environment:
      SYMFONY__ENV__DATABASE_DRIVER: pdo_sqlite
      SYMFONY__ENV__DOMAIN_NAME: https://read.ваш-домен.ru
      SYMFONY__ENV__SERVER_NAME: "Мой архив"
      SYMFONY__ENV__FOSUSER_REGISTRATION: "false"
      SYMFONY__ENV__MAILER_DSN: "null://null"
    volumes:
      - wallabag_data:/var/www/wallabag/data
      - wallabag_images:/var/www/wallabag/web/assets/images

volumes:
  wallabag_data:
  wallabag_images:

Если предполагаете несколько пользователей, активный импорт больших архивов и хотите более предсказуемое поведение под нагрузкой — вынесите базу в PostgreSQL:

services:
  db:
    image: postgres:16-alpine
    container_name: wallabag-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: wallabag
      POSTGRES_PASSWORD: сгенерируйте_свой_пароль
      POSTGRES_DB: wallabag
    volumes:
      - wallabag_db:/var/lib/postgresql/data

  wallabag:
    image: wallabag/wallabag
    container_name: wallabag
    restart: unless-stopped
    depends_on:
      - db
    ports:
      - "8080:80"
    environment:
      SYMFONY__ENV__DATABASE_DRIVER: pdo_pgsql
      SYMFONY__ENV__DATABASE_HOST: db
      SYMFONY__ENV__DATABASE_PORT: 5432
      SYMFONY__ENV__DATABASE_NAME: wallabag
      SYMFONY__ENV__DATABASE_USER: wallabag
      SYMFONY__ENV__DATABASE_PASSWORD: сгенерируйте_свой_пароль
      SYMFONY__ENV__DATABASE_CHARSET: utf8
      SYMFONY__ENV__DOMAIN_NAME: https://read.ваш-домен.ru
      SYMFONY__ENV__SERVER_NAME: "Мой архив"
      SYMFONY__ENV__FOSUSER_REGISTRATION: "false"
      SYMFONY__ENV__MAILER_DSN: "null://null"
    volumes:
      - wallabag_data:/var/www/wallabag/data
      - wallabag_images:/var/www/wallabag/web/assets/images

volumes:
  wallabag_db:
  wallabag_data:
  wallabag_images:

Пара моментов, которые легко упустить. SYMFONY__ENV__FOSUSER_REGISTRATION: "false" отключает публичную самостоятельную регистрацию — по умолчанию она включена, а на сервере с открытым портом это значит, что аккаунт себе может завести кто угодно. SYMFONY__ENV__MAILER_DSN: "null://null" отключает отправку почты (подтверждение регистрации, сброс пароля) — если такой функционал не нужен на личном инстансе, это избавляет от лишних ошибок в логах; если нужен — настройте реальный SMTP отдельно. Volume wallabag_images обязателен даже с SQLite: там хранятся превью и загруженные изображения статей, без него они потеряются при пересоздании контейнера.

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

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

Арендовать сервер

Первый запуск и вход

Сохраните выбранный вариант как docker-compose.yml в отдельной папке на сервере и поднимите стек:

docker compose up -d
docker compose logs -f wallabag

Первый старт устанавливает схему базы и создаёт администратора — это занимает минуту-две, дождитесь в логах строки об успешной установке. Дальше открываете http://IP-сервера:8080 (или уже домен, если настроили DNS заранее) и видите форму входа.

Стандартные учётные данные по умолчанию — логин wallabag, пароль wallabag. Это широко известная пара, и первым же действием после входа зайдите в Настройки → Изменить пароль и смените и логин, и пароль на свои — оставлять дефолт на сервере, торчащем в интернет, нельзя даже на час.

Домен и SSL: reverse-proxy перед контейнером

Открывать Wallabag по IP и порту 8080 без шифрования не стоит — логин и пароль будут уходить открытым текстом, а сам сервис хранит содержимое ваших личных закладок. Самый быстрый способ поднять HTTPS — Caddy с автоматическим Let's Encrypt:

read.ваш-домен.ru {
    reverse_proxy wallabag:80
}

Если Caddy в том же compose-проекте, что и Wallabag, достаточно завести оба сервиса в одну docker-сеть и обращаться по имени сервиса wallabag, как в примере выше. Если Caddy стоит отдельно на том же сервере — используйте reverse_proxy 127.0.0.1:8080 и убедитесь, что порт в docker-compose.yml Wallabag не пробрасывается наружу, кроме как на localhost. Подробности установки Caddy и типичные проблемы с выдачей сертификата (занятый 80-й порт, неправильная A-запись) разобраны в статье про Caddy с авто-SSL на VPS.

После того как домен поднялся по HTTPS, важно, чтобы значение SYMFONY__ENV__DOMAIN_NAME в docker-compose.yml точно совпадало с итоговым https://read.ваш-домен.ru — иначе OAuth2-токены для мобильных клиентов и расширений будут генерироваться с неправильным базовым адресом, и подключение клиентов сломается непредсказуемо.

Если хочется классическую установку без контейнеров — с Nginx, PHP-FPM и системным PostgreSQL, — такой путь тоже описан отдельно, в статье про установку Wallabag на VPS; там же — более развёрнутый разбор Nginx-конфига и cron-бэкапа. Docker Compose из этой статьи — более быстрый и компактный вариант для тех, кто уже привык к контейнерам.

Импорт старых закладок и подключение клиентов

Именно эта часть — главная причина переезжать на Wallabag прямо сейчас, пока экспорт из старых сервисов ещё доступен. В разделе Импорт веб-интерфейса:

  • Pocket — если у вас ещё остался экспортированный файл (Mozilla давала выгрузить данные до осени 2025-го), загружаете его напрямую; если файла нет и API Pocket уже недоступен, восстановить список можно только из ранее сделанного бэкапа браузера или почтовых уведомлений о сохранённых ссылках;
  • Instapaper / Readability — экспортный файл того же формата, что предлагает сам сервис в настройках аккаунта;
  • Другой Wallabag — прямой JSON-экспорт/импорт со всеми тегами, аннотациями и статусом прочитанного, если переносите инстанс с другого сервера;
  • HTML-закладки браузера — стандартный экспорт закладок Firefox или Chrome тоже принимается как список ссылок.

Для повседневного сохранения статей:

  • официальные расширения для Firefox и Chrome — кнопка сохранения прямо на странице;
  • bookmarklet — работает в любом браузере без установки расширения, удобно на рабочих машинах, где нельзя ставить дополнения;
  • мобильное приложение — официальный клиент для Android, для iOS есть сторонние клиенты, работающие через тот же REST API;
  • REST API с OAuth2 (раздел Настройки → API клиенты) — им можно завести собственную автоматизацию, например пересылку ссылок из Telegram-бота.

При настройке любого клиента указываете адрес вашего домена, логин и API-ключ (client id/secret), который генерируется в разделе API клиенты — обычный пароль там не используется, только токен, что безопаснее при утечке настроек клиента.

Бэкап и обновление образа

Данные, которые нужно бэкапить, зависят от выбранного варианта. Для SQLite это только volume wallabag_data (там же лежит сам файл базы) и wallabag_images. Для варианта с PostgreSQL добавляется volume wallabag_db, а бэкап делается дампом:

docker compose exec db pg_dump -U wallabag wallabag | gzip > wallabag-backup-$(date +%F).sql.gz

Общий подход к резервному копированию docker-томов — с ротацией старых копий и переносом на другой сервер или во внешнее хранилище — разобран в статье про бэкап docker volume; логика применима и к SQLite-варианту Wallabag, просто бэкапите весь том wallabag_data целиком.

Обновление до новой версии образа — обычные два шага Compose:

docker compose pull
docker compose up -d

Wallabag сам прогоняет миграции схемы базы при старте новой версии — дополнительных ручных команд обычно не требуется. Тем не менее перед крупным обновлением (например, между мажорными версиями) лишним не будет снять свежий дамп заранее: откатиться на предыдущий образ проще, чем откатывать частично применённую миграцию базы, если что-то пойдёт не так.

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

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

Арендовать сервер

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

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

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

Хватит ли самого дешёвого VPS?

Для одного пользователя с вариантом на SQLite достаточно 1 vCPU и 1 ГБ RAM. С PostgreSQL и несколькими активными пользователями комфортнее закладывать 2 ГБ — парсинг тяжёлых страниц с картинками нагружает PHP-процесс сильнее, чем сама база.

Можно ли перейти с SQLite на PostgreSQL позже, без потери данных?

Прямой автоматической миграции между драйверами базы в Wallabag нет — придётся экспортировать статьи через встроенный JSON-экспорт («другой Wallabag» в разделе импорта на новом инстансе) и импортировать заново в PostgreSQL-версию. Проще сразу выбрать вариант с расчётом на будущее, если ожидаете рост архива.

Почему у части сохранённых статей нет текста, только заголовок?

Обычно виноват парсер контента конкретного сайта — пейволл, JS-рендеринг или нестандартная вёрстка. Помогает кнопка «Обновить контент» на карточке статьи, но не всегда — это известное ограничение экстрактора, а не баг настройки.

Нужен ли Wallabag, если я уже пользуюсь RSS-читалкой?

Это разные задачи. RSS-агрегатор — про поток новых материалов из подписок, Wallabag — про архив конкретных статей «на почитать позже» с офлайн-копией и тегами. Многие держат оба сервиса рядом: интересное из ленты одним кликом улетает в Wallabag на потом.

Можно ли работать с Wallabag без своего домена, просто по IP?

Технически да, но без HTTPS логин и пароль передаются открытым текстом, а мобильные клиенты и расширения могут отказываться работать по обычному HTTP. Для чего-то серьёзнее теста домен с SSL нужен обязательно.

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

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

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