Эта статья устроена как справочник «симптом → причина → что делать». Первым делом при любой проблеме — два источника правды:
docker logs --tail 100 flibusta-fpm # старт, инициализация БД, ошибки PHP
docker compose logs --tail 100 swag # (или ваш reverse proxy)
Где лежат остальные логи — в конце статьи о скриптах.
docker compose up не доходит до запуска контейнеров
Если compose ругается и ни один контейнер не создаётся, дело в самом файле — логов смотреть негде, сообщение приходит от парсера.
services.flibusta-fpm.environment.[16]: unexpected type map[string]interface {}
— в environment есть строка, кончающаяся двоеточием, без кавычек. Почти
всегда это префикс ключей Redis:
- FLIBUSTA_REDIS_PREFIX=flibusta: # ошибка
- "FLIBUSTA_REDIS_PREFIX=flibusta:" # правильно
Двоеточие в конце строки YAML считает признаком ключа, и элемент списка
становится отображением {"FLIBUSTA_REDIS_PREFIX=flibusta": null} вместо
строки. Номер в квадратных скобках — порядковый номер элемента в
environment, считая с нуля и пропуская закомментированные строки.
Сообщение указывает на flibusta-fpm, даже если вы правили совсем другой
сервис: просто именно здесь compose споткнулся первым.
services.<имя> Additional property name is not allowed — у сервиса
указан ключ name. Имя контейнера задаётся как container_name; name
допустим только на верхнем уровне файла и внутри описаний networks,
volumes и secrets.
Полезная привычка: docker compose config печатает файл после разбора и
подстановки переменных, ничего не запуская. Если вывод есть — синтаксис
в порядке, и заодно видно, во что развернулись ${...}.
Контейнер не стартует или сразу останавливается
Смотрите docker logs flibusta-fpm, там будет одна из строк:
<host> is unreachable, can not access DB, exiting — контейнер не
видит Postgres по имени из FLIBUSTA_DBHOST. Проверьте, что оба контейнера
в сети postgres_db_net (docker network inspect postgres_db_net), что
имя хоста — это имя контейнера Postgres, и что Postgres успел стартовать
(увеличьте DB_HOST_PINGS, если он медленный).
Attempt to initialize postgres DB has failed. Cant obtain PG admin password
— роли flibusta ещё нет, а файл из POSTGRES_ADMIN_DBPASSWORD_FILE не
найден или пуст. Проверьте секцию secrets и права на файл (uid 82).
Can't connect to the DB after initialization attempt, exiting —
инициализация прошла с ошибками. Выше в логе будет вывод psql. Обычно это
либо неверный пароль администратора Postgres (частая причина — перевод
строки в конце файла секрета, проверьте wc -l), либо у аккаунта нет
прав CREATEROLE / CREATEDB, либо роль flibusta есть, но пароль в
FLIBUSTA_DBPASSWORD_FILE не тот, что был при создании.
FATAL: directory /flibusta with books is not found — не смонтирован
том с архивами. Директория должна существовать, даже пустая.
Контейнер стартует, но в логе Flibusta DB connection failed — то же,
что предыдущее, но уже из PHP: пароль пользователя flibusta не совпадает.
Соединение с базой открывается при первом обращении к ней, а не при старте,
поэтому такая запись появляется не сразу после запуска контейнера, а при
первом запросе, которому действительно нужна база; в браузере это выглядит
как страница «Database temporarily unavailable».
Reverse proxy отдаёт 502 / 504
502 Bad Gateway — nginx не может достучаться до flibusta-fpm:9000.
Reverse proxy и библиотека должны быть в общей сети flibusta_net; имя
upstream в конфиге — flibusta-fpm (или что в container_name). После
пересоздания контейнера библиотеки nginx иногда держит старый адрес —
docker exec swag nginx -s reload.
504 Gateway Timeout на странице книги — запрос к базе не уложился в таймаут; библиотека сама отдаёт 504 с текстом «Не удалось получить данные книги». Бывает на слабом железе при очень широком поиске; повторите проще.
Страница открывается без стилей, читалки не работают
Статика (/bootstrap/…, /css/…, JS-читалки) отдаётся reverse proxy из
тома flibusta_public_files, а не через PHP. Если её нет — том не
смонтирован в reverse proxy, смонтирован не туда, куда смотрит root в
конфиге, или называется иначе: Docker Compose добавляет к имени тома префикс
проекта (flibusta-at-home_flibusta_public_files). Проверьте docker volume ls и docker inspect у контейнера прокси.
Если стили есть, а pdf не открывается (пустая рамка) — не передаётся
заголовок Content-Security-Policy: worker-src * blob: на ответы PHP.
Вход «по кругу»: после правильного пароля снова форма входа
Cookie сессии помечена как Secure и не отправляется браузером по HTTP.
Поэтому:
- Вход по
http://не работает. Нужен HTTPS. - Вход по HTTPS через reverse proxy, но библиотека думает, что это HTTP —
проверьте
fastcgi_param HTTP_X_FORWARDED_PROTOв конфиге прокси. Признак этой же проблемы — красное предупреждение о HTTP в разделе «Пользователи». - Cookie выставляется на путь из
FLIBUSTA_WEBROOT. Если библиотека доступна по/flibusta, а переменная пустая (или наоборот), cookie уходит не туда. Значение должно совпадать сlocationв прокси, со слэшем в начале и без слэша в конце.
«Сессия формы устарела. Обновите страницу» — не совпал CSRF-токен; чаще всего форма входа была открыта очень давно или в другой вкладке был сделан вход. Просто обновите страницу.
«Session has been terminated for security reasons» — в рамках одной сессии сменился User-Agent. Так бывает при переключении «версии для ПК» в мобильном браузере или при обновлении браузера. Войдите заново.
«Неправильное имя пользователя или пароль» при верном пароле —
аккаунт или адрес заблокирован после серии ошибок (более 10 ошибок для имени
или более 5 с одного адреса за 15 минут). Подождите 15 минут; посмотрите
«Пользователи → Активность пользователей», кто стучался. Если это fail2ban
забанил ваш адрес — fail2ban-client set flibusta unbanip <адрес>.
Доверенная сеть не работает (или работает для всех)
Библиотека сравнивает с FLIBUSTA_TRUSTED_NET значение REMOTE_ADDR,
которое передаёт reverse proxy.
- В логе контейнера строка
FLIBUSTA_TRUSTED_NET value '…' is not a valid IPv4 address or CIDR subnet— опечатка в значении; допустим ровно один адрес или одна подсеть, без кавычек и пробелов. - Пускает без пароля вообще всех —
REMOTE_ADDRсодержит адрес прокси (например,172.18.0.5), который попал в доверенную подсеть. Прокси должен передавать настоящий адрес клиента; при цепочке прокси нуженreal_ip_header. Проверить, какой адрес видит библиотека, проще всего в «Пользователи → Сессии» (колонка «IP входа»). - Не пускает из дома — та же проверка: возможно, домашняя сеть не
192.168.1.0/24, а192.168.0.0/24, или вы заходите через VPN/туннель, и адрес другой.
«Библиотека проходит техническое обслуживание»
Страница с кодом 503 показывается, пока удерживается блокировка обновления базы — во время «Обновить базу данных» или «Сканирование ZIP». Это штатно; страница сама обновляется каждые 30 секунд. Проверить, что операция действительно идёт: раздел «Сервис» (он доступен и в этом режиме) или
docker exec flibusta-fpm ps aux | grep -E 'app_import|app_reindex|update_zip'
Блокировка — flock; если процесса нет, блокировки тоже нет. «Зависшего»
режима техобслуживания не существует; если 503 держится, а процессов нет —
это reverse proxy кэширует ответ, или вы смотрите на другую установку.
Если импорт был прерван (перезагрузка хоста) — просто запустите «Обновить базу данных» ещё раз.
«Session store temporarily unavailable» и 503 на всех страницах
Это не техобслуживание, а недоступный Redis. Сообщение появляется, только
если задана переменная FLIBUSTA_REDIS_HOST: библиотека намеренно не
откатывается молча на сессии в Postgres, потому что сессии, разъехавшиеся по
двум хранилищам, выглядели бы как случайные разлогинивания.
Проверьте по порядку:
docker ps | grep redis # контейнер вообще запущен?
docker exec flibusta-fpm php -r 'echo extension_loaded("redis") ? "ext ok\n" : "NO EXT\n";'
docker exec flibusta-fpm sh -c 'php -r "\$r=new Redis(); var_dump(\$r->connect(getenv(\"FLIBUSTA_REDIS_HOST\"), (int)(getenv(\"FLIBUSTA_REDIS_PORT\")?:6379), 1));"'
Частые причины: Redis и библиотека не в общей сети Docker; имя хоста в
FLIBUSTA_REDIS_HOST не совпадает с именем контейнера; задан
requirepass, а пароль библиотеке не передан.
Первая причина ловит чаще всего, и незаметно: если у сервиса библиотеки
сети перечислены явно (flibusta_net, postgres_db_net), а у сервиса
Redis секции networks нет вовсе, Redis попадает в сеть default, которую
compose создаёт сам, — библиотеки там нет, и имя flibusta-redis просто не
разрешается. Сети по умолчанию наследуют не все сервисы, а только те, у
которых список не задан, так что добавьте Redis в flibusta_net явно. Точная причина будет в
docker logs flibusta-fpm — там же строка о том, что Redis недоступен.
Отдельный случай — NOAUTH Authentication required. в логе рядом с
session write failed, причём страницы при этом открываются (код 200, а не
503). Это значит, что Redis запущен с requirepass, соединение установилось,
а библиотека пароль не отправила: подключение само по себе аутентификации не
требует, и промах вылезает только на первой настоящей команде. Причина всегда
в конфигурации библиотеки, а не Redis — проверьте, что у сервиса
flibusta-fpm есть и переменная FLIBUSTA_REDIS_PASSWORD_FILE, и сам
секрет в его секции secrets (объявить секрет только у сервиса Redis
недостаточно), и что файл читается пользователем php-fpm:
docker exec flibusta-fpm env | grep -i redis
docker exec -u www-data flibusta-fpm sh -c 'wc -c < /run/secrets/FLIBUSTA_REDIS_PWD'
Начиная с версии, где это поведение исправлено, нечитаемый или пустой файл
пароля даёт честную 503 и строку cannot read FLIBUSTA_REDIS_PASSWORD_FILE
вместо потока NOAUTH.
Быстрый обходной путь, если Redis чинить некогда: уберите
FLIBUSTA_REDIS_HOST и пересоздайте контейнер — библиотека вернётся к
сессиям в Postgres. Читателям придётся войти заново. Подробнее — в
статье о кэше.
Показываются старые данные книги после импорта
Кэш описаний книг (только в конфигурации с Redis) привязан к «поколению библиотеки», которое увеличивают импорт дампа и сканирование ZIP. Если каталог обновился, а на странице книги старая аннотация или старое название, значит счётчик не увеличился — как правило, потому что импорт завершился с ошибкой до последнего шага. Сбросить кэш вручную:
docker exec -u www-data flibusta-fpm php /tools/cache_bump.php
Команда безопасна, её можно выполнять когда угодно: она лишь помечает все закэшированные описания как устаревшие. Без Redis она ничего не делает.
Если же расходится не описание книги, а то, в каком архиве она лежит («книга не найдена» после добавления архивов), — это индекс архивов, см. следующий раздел.
Книга не открывается
«Книга не найдена» / файл недоступен при том, что книга есть в каталоге. Каталог строится по базе, а файлы — по индексу архивов. Варианты:
-
Не выполнено «Сканирование ZIP» после добавления архивов. Выполните.
-
Архив есть, но не проиндексирован: имя не по схеме (нужен дефис,
.zip, подстрокаfb2для fb2-архивов) или нет прав на чтение для uid 82. Смотрите/cache/log/update_zip_list.log, таблицуbook_zipи файл/cache/zip_index.php— именно из него библиотека берёт соответствие «книга → архив». Сканирование перестраивает и таблицу, и файл; если они разошлись (например, файл удалили руками), достаточно перезапустить контейнер или выполнитьdocker exec -u www-data flibusta-fpm php /tools/build_zip_index.php --force. -
Диапазоны архивов не покрывают этот id (
Got a gapв том же логе) — книги из разрыва отсутствуют физически; либо докачайте архив, либо включите скачивание на лету. -
Архив повреждён: в логе контейнера
book_open_source: cannot open archive …. Проверьтеunzip -t <файл>и перекачайте. -
Режим «на лету» включён, но в логе
fetchMissingBook: failed to download … (HTTP <код>)— Флибуста недоступна с сервера, сменился домен или книга удалена. Проверьте доступность:docker exec flibusta-fpm curl -sI "$FLIBUSTA_URL" | head -1
Книга большая и предлагается только скачать. fb2 крупнее
MAX_FB2_SIZE_2_DISPLAY (по умолчанию 100 МБ) в браузере не рендерится —
намеренно.
Скачивание в epub/kfx/azw8 отдаёт ошибку. В логе контейнера будет
fb2.php fbc failed for book … с выводом конвертера — как правило, это
битый fb2 (невалидный XML). Скачайте fb2 как есть и конвертируйте
локально, или сообщите об ошибке в проект.
Нет обложек
- Не запускалась «Скачать обложки» — обложки берутся из архивов
lib.b.attached.zip(книги) иlib.a.attached.zip(авторы) в/cache. - Обложка отсутствовала при прошлом обращении, и библиотека это
запомнила: в
/cache/covers/<id>.noneставится отметка, чтобы не искать снова. Отметка автоматически теряет силу, когда архив обложек обновится («Скачать обложки»), и удаляется кнопкой «Очистить кэш». - В логе
extract_cover: cannot write miss marker … is /cache/covers/ writable?— права на/cache/covers, см. следующий раздел. - Для fb2 без обложки в архиве библиотека пытается вытащить обложку из самого файла; если её там нет — будет заглушка, это нормально.
Ошибки прав доступа: «Permission denied», операции молча не работают
Всё в /cache и /sql должно принадлежать uid 82. Обычные причины
нарушения: файлы созданы docker exec без -u www-data, директории
скопированы с другого хоста rsync без сохранения владельца, том NAS с
принудительным владельцем. Лечение:
docker restart flibusta-fpm # entrypoint делает chown -R www-data /cache /sql
или на хосте chown -R 82:82 /opt/flibusta/cache /opt/flibusta/sql. Для
/flibusta достаточно права чтения; проверка изнутри контейнера:
docker exec -u www-data flibusta-fpm sh -c 'ls /flibusta | head; touch /cache/tmp/probe && echo cache OK'
Импорт дампа падает
Смотрите /cache/log/dbupdate.log. Частые причины:
- Нет места в
/sql: дампы распаковываются на месте, нужно несколько гигабайт сверх размера.gz. - Нет места в Postgres (том базы).
- Сообщение
gzip: /sql/*.gz: No such file or directoryв начале — не ошибка: дампы уже были распакованы прошлым импортом. - Импорт прерван — запустите ещё раз, он идемпотентен.
Если дампы скачались не полностью («Скачать базу» прервалась), удалите
битый .gz из /sql и файл с тем же именем из /cache/etag/, иначе
библиотека решит, что версия актуальна, и не перекачает.
«Скачать последние обновления» ничего не скачивает
- Перед скачиванием сравнивается ETag с сохранённым в
/cache/etag/;local version of … remains currentв выводе означает «уже есть». Чтобы принудительно перекачать файл, удалите его ETag-файл. - Флибуста недоступна с сервера — см. проверку
curlвыше. В России доступ к домену может быть заблокирован; варианты — другое зеркало вFLIBUSTA_URLили прокси через переменныеhttps_proxyвenvironment. - Скрипт не смог взять блокировку (
failed to obtain admin op lock) — идёт другая операция, подождите.
Загрузка файла в «Добавить» или torrent-файла не проходит
Лимит PHP — 500 МБ (upload_max_filesize) при post_max_size 508 МБ.
Если ошибка «слишком велик» при файле меньше — упирается reverse proxy:
client_max_body_size в nginx, лимит запроса у Cloudflare (100 МБ на
бесплатном тарифе) и т.п.
Часы и время
Время операций в «Сервисе», лог попыток входа и cron живут в разных
часовых поясах, если TZ контейнера не совпадает с хостом. Симптомы:
fail2ban не банит (записи «из будущего»), отметки времени на странице
«Сервис» отличаются от ожидаемых на несколько часов. Задайте TZ в
environment равным часовому поясу хоста.
Если ничего не помогло
Соберите docker logs flibusta-fpm, лог reverse proxy, вывод последней
операции из «Сервиса», версию образа (docker inspect flibusta-fpm | grep -i image) и опишите проблему в issues проекта на
GitHub. Пароли и адреса из
логов перед публикацией уберите.