MAATRIX / Блог / Как установить и настроить Wallabag на VPS

Как установить и настроить Wallabag на VPS

MAATRIX

После закрытия Pocket многие читатели остались без привычного «сохранить на потом», а альтернативы вроде Instapaper требуют доверять чужому облаку и подписке. Wallabag решает это проще: open-source read-it-later сервис, который вы разворачиваете на своём VPS за 15-20 минут, храните статьи в своей базе и открываете их с телефона, браузера или по RSS без единого стороннего сервера между вами и вашими закладками.

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

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

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

Что такое Wallabag и когда он нужен

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

От Pocket и Instapaper он отличается тем, что все данные — ваши, физически лежат на вашем сервере, и никто не может закрыть сервис или изменить условия подписки. От RSS-читалок вроде FreshRSS или Miniflux — тем, что заточен не под подписки на ленты, а именно под ручное сохранение конкретных статей и книгодочтение (есть даже встроенная оценка «сколько минут читать»).

Разумный сценарий — держать Wallabag рядом с уже развёрнутым self-hosted стеком: например, FreshRSS собирает ленты, а интересные статьи оттуда одним кликом улетают в Wallabag на прочтение. Это два разных инструмента, и путать их не стоит — RSS-читалка про поток, Wallabag про архив.

Требования к серверу и подготовка VPS

Wallabag — приложение на PHP/Symfony, само по себе нетяжёлое, но вместе с PostgreSQL и веб-сервером под Docker комфортно чувствует себя на:

РесурсМинимумКомфортно (500+ статей, несколько пользователей)
CPU1 vCPU2 vCPU
RAM1 GB2 GB
Диск10 GB20-30 GB SSD
ОСUbuntu 24.04 / Debian 12

Основной расход диска — не сама база, а сохранённые изображения и офлайн-копии статей: если вы активно сохраняете лонгриды с картинками, за год-два наберётся несколько гигабайт.

Перед установкой:

  1. Заведите домен или поддомен (например, read.example.com) и направьте A-запись на IP вашего VPS.
  2. Обновите систему и поставьте Docker с Compose-плагином:
apt update && apt upgrade -y
curl -fsSL https://get.docker.com | sh
docker --version && docker compose version
  1. Настройте фаервол — открытыми снаружи должны быть только 22 (SSH), 80 и 443. Если ещё не делали это на сервере, разберитесь в настройке UFW — это займёт пять минут и закроет очевидные дыры.

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

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

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

Установка Wallabag через Docker Compose

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

Создайте директорию проекта и файл окружения:

mkdir -p /opt/wallabag && cd /opt/wallabag
nano .env
# .env
POSTGRES_DB=wallabag
POSTGRES_USER=wallabag
POSTGRES_PASSWORD=сгенерируйте_длинный_пароль
WALLABAG_DOMAIN=https://read.example.com

Теперь docker-compose.yml:

services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - ./data/postgres:/var/lib/postgresql/data

  wallabag:
    image: wallabag/wallabag
    restart: unless-stopped
    depends_on:
      - postgres
    ports:
      - "127.0.0.1:8080:80"
    environment:
      SYMFONY__ENV__DATABASE_DRIVER: pdo_pgsql
      SYMFONY__ENV__DATABASE_HOST: postgres
      SYMFONY__ENV__DATABASE_PORT: 5432
      SYMFONY__ENV__DATABASE_NAME: ${POSTGRES_DB}
      SYMFONY__ENV__DATABASE_USER: ${POSTGRES_USER}
      SYMFONY__ENV__DATABASE_PASSWORD: ${POSTGRES_PASSWORD}
      SYMFONY__ENV__DATABASE_CHARSET: utf8
      SYMFONY__ENV__DOMAIN_NAME: ${WALLABAG_DOMAIN}
      SYMFONY__ENV__SERVER_NAME: "Мой Wallabag"
      SYMFONY__ENV__FOSUSER_REGISTRATION: "false"
      SYMFONY__ENV__MAILER_DSN: "null://null"
    volumes:
      - ./data/wallabag/images:/var/www/wallabag/web/assets/images
      - ./data/wallabag/data:/var/www/wallabag/data

Порт контейнера намеренно проброшен только на 127.0.0.1:8080 — снаружи Wallabag будет доступен исключительно через Nginx с HTTPS, напрямую по IP:8080 достучаться не получится, и это правильно.

SYMFONY__ENV__FOSUSER_REGISTRATION: "false" сразу отключает публичную регистрацию — по умолчанию она включена, и на сервере, торчащем в интернет, это создаёт пользователей всем желающим. Оставьте true только на время, пока заводите нужные аккаунты вручную, потом выключите.

Запускаем:

docker compose up -d
docker compose logs -f wallabag

Первый запуск установит схему базы и создаст дефолтного администратора — дождитесь строки wallabag has been successfully installed в логах, это займёт минуту-две.

Nginx и HTTPS через Let's Encrypt

Снаружи открывать порт 8080 напрямую не нужно — ставим Nginx как обратный прокси. Если ещё не настраивали такую связку, посмотрите общий разбор Nginx как reverse proxy, здесь — конфиг конкретно под Wallabag:

# /etc/nginx/sites-available/wallabag
server {
    listen 80;
    server_name read.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        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;
        client_max_body_size 20m;
    }
}
ln -s /etc/nginx/sites-available/wallabag /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

Дальше — сертификат. Подробный разбор процесса и типичных грабель есть в статье про Let's Encrypt SSL, команда для стандартного случая:

apt install -y certbot python3-certbot-nginx
certbot --nginx -d read.example.com

Certbot сам допишет блок listen 443 ssl и настроит редирект с 80 на 443. Проверьте, что после выпуска сертификата сайт открывается по https://read.example.com и Wallabag показывает форму входа, а не ошибку 502 — если видите 502, значит контейнер ещё не успел подняться или порт в конфиге Nginx не совпадает с docker-compose.yml.

Первый вход, импорт статей и клиенты

Дефолтные учётные данные после установки — wallabag / wallabag. Первым делом зайдите в Настройки → Изменить пароль и смените и логин, и пароль — это публично известная пара, и оставлять её вы не должны ни на минуту.

Импорт старых закладок делается в разделе Импорт:

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

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

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

Каждый тег в Wallabag можно экспортировать обратно в RSS — это удобно, если хотите читать «непрочитанное» через привычную RSS-читалку вроде Miniflux.

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

Данные Wallabag — это база PostgreSQL плюс папка с сохранёнными изображениями. Оба тома уже лежат в ./data рядом с docker-compose.yml, но полагаться на «файлы просто лежат на диске» не стоит — нужен регулярный дамп.

Простой скрипт для cron:

#!/bin/bash
# /opt/wallabag/backup.sh
DATE=$(date +%F)
BACKUP_DIR=/opt/wallabag/backups
mkdir -p $BACKUP_DIR

docker compose -f /opt/wallabag/docker-compose.yml exec -T postgres \
  pg_dump -U wallabag wallabag | gzip > "$BACKUP_DIR/wallabag-$DATE.sql.gz"

tar czf "$BACKUP_DIR/images-$DATE.tar.gz" -C /opt/wallabag/data/wallabag images

find $BACKUP_DIR -type f -mtime +14 -delete
chmod +x /opt/wallabag/backup.sh
crontab -e
# 0 3 * * * /opt/wallabag/backup.sh

Общие принципы бэкапа Postgres-баз и типичные ошибки при их восстановлении разобраны в статье про бэкап MySQL на VPS — логика с pg_dump и планировщиком та же, меняется только команда дампа. Копии лучше держать не только на самом сервере, а хотя бы иногда синкать во внешнее хранилище (объектное хранилище или другой сервер) — если пропадёт диск целиком, локальные бэкапы не спасут.

Обновление до новой версии образа:

cd /opt/wallabag
docker compose pull
docker compose up -d
docker compose logs -f wallabag

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

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

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

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

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

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

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

Хватит ли 1 ГБ RAM?

Для одного-двух пользователей и не самой интенсивной подгрузки статей — да, но с запасом лучше 2 ГБ: PHP-FPM и Postgres вместе на пике парсинга тяжёлых страниц с картинками могут прижать 1 ГБ к пределу.

Можно обойтись без Postgres, на SQLite?

Технически да — Wallabag поддерживает pdo_sqlite, это проще для теста на минимальном VPS, но для боевого использования с несколькими пользователями и активным полнотекстовым поиском PostgreSQL надёжнее под конкурентной нагрузкой.

Почему после сохранения статья приходит без текста, только заголовок?

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

Нужен ли Wallabag, если уже есть FreshRSS?

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

Как перенести Wallabag на другой сервер?

Скопируйте docker-compose.yml, .env, папку data целиком (включая дамп/файлы Postgres) на новый VPS и поднимите docker compose up -d — приложение не привязано к железу и просто продолжит работать с той же базой.

Безопасно ли открывать API наружу?

Да, если он идёт через тот же HTTPS-домен с Nginx — API использует OAuth2-токены, а не хранит пароль в открытом виде на клиентах.

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

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

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