Wallabag на сервере: частые ошибки и решения
Wallabag поднимается быстро — контейнер запустился, интерфейс открылся, а через неделю-другую начинаются сюрпризы: то статьи не сохраняются, то картинки не подгружаются, то cron молча перестаёт разбирать очередь. Проблема в том, что Wallabag собирает вокруг себя несколько движущихся частей — PHP, базу, парсер контента, очередь фоновых задач — и падает обычно не сам сервис, а что-то на стыке между ними. Разберём конкретные симптомы и как их лечить, без гадания.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Белый экран или 500-я ошибка после установки
Классика: контейнер поднялся, порт слушается, но https://read.example.com отдаёт белую страницу или голый 500 Internal Server Error без деталей. Первым делом смотрим логи самого приложения, а не веб-сервера перед ним:
docker compose logs -f wallabag --tail=100
Чаще всего там лежит одна из трёх причин:
- Не сгенерирован APP_SECRET — если вы копировали
.envиз примера и не заменили значение по умолчанию, Symfony (на нём построен Wallabag) откажется работать в проде. Сгенерируйте случайную строку:
openssl rand -hex 16
и подставьте её в переменную SYMFONY__ENV__SECRET в .env или docker-compose.yml, затем пересоздайте контейнер (docker compose up -d --force-recreate wallabag).
- Права на директорию
var/— Wallabag внутри контейнера пишет кэш, логи и сессии в/var/www/wallabag/var. Если том примонтирован с UID хоста, а процесс внутри контейнера работает от другого пользователя, запись падает молча, а наружу вылезает 500-я. Проверьте:
docker compose exec wallabag ls -la /var/www/wallabag/var
docker compose exec wallabag chown -R www-data:www-data /var/www/wallabag/var
- Кэш не пересобран после апдейта — после
docker compose pull && docker compose up -dиногда остаётся старый скомпилированный кэш Symfony на смонтированном томе. Чистим руками:
docker compose exec wallabag bin/console cache:clear --env=prod --no-debug
Если ошибка сохраняется, включите подробный вывод временно (APP_DEBUG=1 в .env только на время диагностики, не в проде) — так вы увидите реальный стектрейс вместо общей 500-й.
База данных: SQLite вместо PostgreSQL и наоборот
Wallabag поддерживает SQLite, MySQL/MariaDB и PostgreSQL. Официальный Docker-образ по умолчанию тянет за собой SQLite-файл внутри контейнера — удобно для теста, но плохая идея для боевого сервера: файл живёт в контейнере, любой docker compose down -v или пересборка образа может его унести с собой, а конкурентная запись на SQLite при активном использовании (несколько устройств синхронизируются одновременно) иногда даёт database is locked.
Если видите в логах:
SQLSTATE[HY000]: General error: 5 database is locked
— это почти наверняка SQLite под нагрузкой. Переезд на PostgreSQL решает вопрос радикально. Минимальный фрагмент docker-compose.yml:
services:
wallabag:
image: wallabag/wallabag
environment:
- SYMFONY__ENV__DATABASE_DRIVER=pdo_pgsql
- SYMFONY__ENV__DATABASE_HOST=wallabag-db
- SYMFONY__ENV__DATABASE_PORT=5432
- SYMFONY__ENV__DATABASE_NAME=wallabag
- SYMFONY__ENV__DATABASE_USER=wallabag
- SYMFONY__ENV__DATABASE_PASSWORD=change_me
depends_on:
- wallabag-db
wallabag-db:
image: postgres:16-alpine
environment:
- POSTGRES_DB=wallabag
- POSTGRES_USER=wallabag
- POSTGRES_PASSWORD=change_me
volumes:
- wallabag_db_data:/var/lib/postgresql/data
volumes:
wallabag_db_data:
После смены драйвера база пустая — данные из SQLite сами не переедут. Экспортируйте статьи из старого инстанса в формате JSON или Wallabag-бэкапа через Настройки → Экспорт вашей учётной записи Wallabag, поднимите новый инстанс на PostgreSQL и импортируйте обратно через bin/console wallabag:import.
Отдельно проверьте, что миграции реально применились после смены драйвера или обновления версии:
docker compose exec wallabag bin/console doctrine:migrations:status
docker compose exec wallabag bin/console doctrine:migrations:migrate --no-interaction
Пропущенная миграция — вторая по частоте причина случайных 500-х после апдейта образа.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверСтатьи сохраняются, но без содержимого
Пользователь жмёт "Сохранить статью", запись появляется в списке, но открывается пустой — заголовок есть, текста нет. Это парсер контента (Graby, форк php-readability) не смог вытащить статью со страницы-источника. Причины по убыванию частоты:
- Исходящих запросов с сервера не пропускает файрвол или DNS не резолвит внешние домены. Проверьте руками:
docker compose exec wallabag curl -I https://example.com/some-article
Если таймаут — смотрите правила исходящего трафика на сервере, это не проблема Wallabag.
- Сайт-источник отдаёт контент только с реальным User-Agent браузера или через JS-рендеринг (SPA-статьи, некоторые платные издания). Graby не выполняет JavaScript — если весь текст рендерится на клиенте, парсер увидит пустой
<div id="app">. Обходного пути на уровне Wallabag нет, разве что настроить сайт-специфичные правила извлечения (Site Config) вapp/config/wallabag/site_config— Wallabag поддерживает кастомные конфиги для конкретных доменов в стиле fivefilters.
- Устаревшие site-config правила. Обновите встроенный набор:
docker compose exec wallabag bin/console wallabag:import:redis-worker
на деле сами конфиги подтягиваются при апдейте образа — если вы давно не обновляли контейнер, подтяните свежий тег.
Фоновая очередь и импорт не работают без cron
Wallabag умеет импортировать статьи из Pocket, Instapaper, Readability и других сервисов, а также обрабатывать очередь через RabbitMQ/Redis для асинхронного разбора большого объёма ссылок. Если после запуска импорта прогресс-бар замер на 0% и ничего не происходит — скорее всего, воркер очереди просто не запущен как отдельный процесс. В официальном образе это не поднимается автоматически, нужен второй контейнер или systemd-юнит:
docker compose exec -d wallabag bin/console wallabag:import:redis-worker Wallabag\\Import\\Pocket\\PocketImport
Для регулярных задач (очистка старых сессий, проверка "мёртвых" ссылок через wallabag:clean-duplicates) удобнее вынести вызовы в системный cron хоста, а не пытаться держать процесс живым внутри контейнера бесконечным sleep-циклом — так проще следить за логами и перезапуском при сбое. Если cron на сервере вообще ведёт себя странно (задачи не срабатывают, PATH внутри cron не совпадает с интерактивным шеллом), это отдельная и частая головная боль — разбор типичных граблей есть в статье про настройку cron-задач на сервере.
Reverse-proxy и HTTPS: редиректы уходят на http
Если Wallabag стоит за Nginx или Caddy с TLS-терминацией на прокси, частая жалоба — после логина браузер редиректит на http:// вместо https://, и сессия рвётся с ошибкой CSRF-токена. Причина в том, что приложение внутри контейнера не знает, что запрос пришёл по HTTPS — оно видит только внутренний http-трафик от прокси.
Убедитесь, что прокси прокидывает заголовки:
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
а в .env Wallabag выставлен правильный SYMFONY__ENV__DOMAIN_NAME (полный URL с https://, без завершающего слэша). Без этого приложение генерирует ссылки и redirect'ы с http-схемой, а браузер с включённым HSTS их просто блокирует, что выглядит как "сайт не открывается" при полностью рабочем сервере.
Если вы ещё не определились, что ставить перед Wallabag — Nginx или Caddy — у нас есть сравнение подходов в статье Caddy или Nginx: что выбрать для сервера, а конкретные грабли с авто-выпуском сертификата в Caddy разобраны в статье про Caddy с авто-SSL на сервере.
Медленный отклик и рост потребления памяти
Wallabag на минимальной конфигурации (1 vCPU / 1 ГБ RAM) обычно работает нормально для личного использования, но при активном импорте сотен статей за раз или при регулярном фоновом фетче RSS-подписок (если вы используете Wallabag и как read-it-later, и как агрегатор) память может упираться в лимит контейнера, и процесс PHP-FPM начинает падать по OOM.
Симптомы в dmesg или docker inspect <container> --format='{{.State.OOMKilled}}' дадут точный ответ, убивал ли контейнер именно OOM-killer. Если да — варианта два: поднять лимит памяти у контейнера (mem_limit в compose или --memory при запуске) или увеличить своп на сервере, если апгрейд тарифа сейчас не вариант. Общий разбор, зачем и как настраивать swap на VPS, — в статье swap и производительность с нуля (подход применим и на Debian/Ubuntu, меняются только команды пакетного менеджера).
Отдельно проверьте настройки PHP-FPM внутри контейнера — по умолчанию число дочерних процессов (pm.max_children) может быть избыточным для маленького сервера, и каждый процесс тянет свою долю памяти даже в простое. Если контейнер стабильно съедает больше, чем вы ожидали, при пустом трафике — это первое, куда смотреть.
Если проблема не в самом Wallabag, а в контейнере в целом (не стартует, сразу падает, не пробрасывается порт) — общие причины и решения для Docker-контейнеров разобраны в статье Docker-контейнер не запускается, там же есть чек-лист диагностики, применимый к любому self-hosted сервису на Docker, включая Wallabag.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Wallabag поддерживает несколько пользователей на одном инстансе?
Да, встроенная система пользователей и клиентов API есть из коробки — регистрация создаётся администратором через консоль (bin/console fos:user:create) или разрешается публично в настройках, если это домашний сервер для семьи, а не публичный сервис.
Можно ли перенести Wallabag с одного VPS на другой без потери статей?
Да, самый надёжный способ — снять полный дамп базы (pg_dump для PostgreSQL или mysqldump для MySQL) плюс скопировать том с загруженными изображениями статей (/var/www/wallabag/web/assets/images в контейнере), развернуть тот же стек на новом сервере и восстановить оба тома до первого запуска.
Почему не подгружаются картинки в сохранённых старых статьях?
Wallabag по умолчанию скачивает и хранит изображения локально при сохранении статьи. Если том с картинками был утерян при пересборке контейнера (например, использовался анонимный том без явного volume в compose-файле), изображения не восстановятся — сам текст статьи при этом остаётся целым, потому что хранится в базе отдельно.
Официальный Docker-образ Wallabag официально поддерживается?
Образ публикует и поддерживает команда проекта, но релизы иногда отстают от GitHub-тегов на несколько недель — если нужна самая свежая версия с фиксом конкретного бага, иногда быстрее собрать образ из исходников Dockerfile в репозитории проекта, чем ждать обновления на Docker Hub.
Как быстро проверить, что Wallabag вообще может достучаться до интернета из контейнера?
Простейший тест — зайти в контейнер и curl'ом дёрнуть любой внешний URL: docker compose exec wallabag curl -I https://ya.ru. Если запрос виснет или обрывается — проблема на уровне сети Docker или файрвола хоста, а не в самом приложении.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →