Как установить и настроить Wallabag на VPS
После закрытия 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+ статей, несколько пользователей) |
|---|---|---|
| CPU | 1 vCPU | 2 vCPU |
| RAM | 1 GB | 2 GB |
| Диск | 10 GB | 20-30 GB SSD |
| ОС | Ubuntu 24.04 / Debian 12 | — |
Основной расход диска — не сама база, а сохранённые изображения и офлайн-копии статей: если вы активно сохраняете лонгриды с картинками, за год-два наберётся несколько гигабайт.
Перед установкой:
- Заведите домен или поддомен (например,
read.example.com) и направьте A-запись на IP вашего VPS. - Обновите систему и поставьте Docker с Compose-плагином:
apt update && apt upgrade -y
curl -fsSL https://get.docker.com | sh
docker --version && docker compose version
- Настройте фаервол — открытыми снаружи должны быть только 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 ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →