Mealie на сервере: частые ошибки и решения
Mealie — удобный self-hosted менеджер рецептов с планированием меню и автоматическим списком покупок, но на практике он капризнее, чем кажется по документации: контейнер падает после обновления, парсер рецептов по ссылке возвращает пустоту, а список покупок теряет часть позиций. Разбираем самые частые проблемы Mealie на сервере и рабочие способы их решить — без лишней теории, только то, что реально помогает.
Содержание
- Контейнер не стартует после обновления образа
- Импорт рецептов по URL не работает
- Список покупок теряет позиции или дублируется
- Медленный поиск и зависания на большой базе рецептов
- Планировщик меню не показывает рецепты или сбрасывает план
- HTTPS, обратный прокси и проблемы с загрузкой изображений
- Резервное копирование и перенос на новый сервер
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Контейнер не стартует после обновления образа
Самая частая жалоба — после docker compose pull && docker compose up -d Mealie либо не поднимается, либо крутится в рестарте. Обычно причина в одном из трёх мест.
Во-первых, начиная с версии 1.x Mealie переехал на новую схему базы (миграция с TinyDB/SQLite на строгий Alembic-цикл в некоторых релизах), и если контейнер запускается от предыдущего мажорного релиза сразу на несколько версий вперёд — миграция ломается. Смотрите логи:
docker compose logs -f mealie
Если видите ошибку вида alembic.util.exc.CommandError или relation "X" does not exist — не пытайтесь чинить руками, откатитесь на предыдущий тег образа, дайте контейнеру нормально стартовать, затем поднимайте версию постепенно, шаг за шагом, а не через несколько релизов разом.
Во-вторых, проверьте права на volume с данными:
docker compose exec mealie ls -la /app/data
Если владелец не совпадает с UID, под которым работает процесс (обычно это фиксируется через PUID/PGID в .env), Mealie не сможет писать в базу и упадёт с ошибкой доступа. Исправляется так:
sudo chown -R 911:911 ./mealie-data
(911 — стандартный UID/GID образа mealie:latest на базе LinuxServer-подобных практик; уточняйте в конкретном образе, если используете форк).
В-третьих, память. Mealie на старте прогревает индекс поиска и парсер рецептов, и на VPS с 1 ГБ RAM это иногда убивает процесс через OOM-killer:
dmesg -T | grep -i "killed process"
Если видите mealie в списке — либо добавляйте swap, либо переезжайте на тариф с 2 ГБ памяти, комфортного минимума для стабильной работы связки Mealie + база + Redis (если используется).
Импорт рецептов по URL не работает
Mealie умеет вытаскивать рецепт по ссылке через парсер JSON-LD/microdata, но на части сайтов это не срабатывает. Причины делятся на три группы.
Сайт отдаёт другой контент ботам. Многие рецептные блоги проверяют User-Agent и капчу, отдавая серверным запросам заглушку. Проверить просто:
docker compose exec mealie curl -sI -A "Mozilla/5.0" https://example.com/recipe
Если код ответа не 200 или тело сильно отличается от того, что видно в браузере — сайт блокирует автоматические запросы, и это не чинится на стороне Mealie.
У сайта нет структурированной разметки рецепта. Парсер Mealie ищет схему Recipe в JSON-LD. Если у сайта её нет (или она сломана), импорт вернёт пустую карточку или только заголовок. Проверить наличие разметки можно так:
curl -s https://example.com/recipe | grep -o '"@type":"Recipe"'
Пусто — разметки нет, придётся вносить рецепт вручную или через bookmarklet (в Mealie есть встроенный JS-букмарклет для полуавтоматического захвата со страницы).
DNS или исходящий трафик блокируются файрволом. Если контейнер вообще не может достучаться до внешнего интернета:
docker compose exec mealie curl -v https://google.com
Таймаут здесь почти всегда означает, что docker-сеть не проброшена наружу или на хосте закрыт исходящий 443/80. На VPS с настроенным UFW проверьте:
sudo ufw status
и убедитесь, что исходящие соединения (OUT) не заблокированы политикой по умолчанию.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверСписок покупок теряет позиции или дублируется
Это баг, с которым сталкивались многие, и связан он с тем, как Mealie объединяет одинаковые ингредиенты из разных рецептов в один пункт списка. Если ингредиент в одном рецепте назван «лук репчатый», а в другом просто «лук» — Mealie не всегда их сливает, и вы получаете два отдельных пункта вместо одного суммированного.
Частичное решение — стандартизировать названия ингредиентов через раздел Data Management → Foods в админке: там можно объединить дубли (merge) в один канонический food-объект. Это не автоматизируется полностью, но после разовой чистки список покупок собирается заметно чище.
Если позиции полностью пропадают (а не дублируются) — чаще всего дело в том, что ингредиент не привязан к food-объекту вообще (это может произойти при импорте по URL, когда парсер не смог сопоставить строку с существующим food). Такие «сиротские» ингредиенты Mealie иногда не подтягивает в список покупок корректно. Проверяйте карточку рецепта после импорта — если ингредиент подсвечен как несвязанный, свяжите его вручную.
Медленный поиск и зависания на большой базе рецептов
При коллекции от нескольких сотен рецептов поиск может начать тормозить, особенно если используется дефолтная база SQLite вместо PostgreSQL. Mealie поддерживает оба варианта, и для баз побольше однозначно стоит переходить на Postgres:
services:
mealie:
image: ghcr.io/mealie-recipes/mealie:latest
environment:
DB_ENGINE: postgres
POSTGRES_SERVER: mealie-db
POSTGRES_PORT: 5432
POSTGRES_DB: mealie
POSTGRES_USER: mealie
POSTGRES_PASSWORD: ${DB_PASSWORD}
depends_on:
- mealie-db
mealie-db:
image: postgres:16-alpine
volumes:
- ./pg-data:/var/lib/postgresql/data
environment:
POSTGRES_DB: mealie
POSTGRES_USER: mealie
POSTGRES_PASSWORD: ${DB_PASSWORD}
restart: unless-stopped
Важный нюанс: миграция с SQLite на Postgres на живой базе не делается «на лету» переключением переменной окружения — данные нужно экспортировать (в Mealie есть встроенный экспорт бэкапа через Settings → Backups) и импортировать заново на чистой Postgres-инсталляции. Планируйте окно на это заранее, особенно если база рецептов накопилась большая.
Второй источник тормозов — полнотекстовый поиск с OCR/эмбеддингами, если включена ИИ-функциональность (распознавание рецептов с фото). Это ощутимо грузит CPU на слабых тарифах. Если функция не критична — отключите её в настройках, это снимет фоновую нагрузку.
Планировщик меню не показывает рецепты или сбрасывает план
Известная жалоба — план меню на неделю иногда пропадает после обновления контейнера. Это связано с тем, что таблица планировщика в некоторых релизах меняла схему, и при миграции без резервной копии часть данных планировщика могла не перенестись корректно.
Практическое правило: перед любым обновлением делайте бэкап через встроенный механизм (Settings → Backups → Create Backup) или бэкапьте volume с базой снаружи:
docker compose exec mealie-db pg_dump -U mealie mealie > mealie-backup-$(date +%F).sql
Если используете SQLite — просто копируйте файл базы из volume:
docker cp $(docker compose ps -q mealie):/app/data/mealie.db ./mealie-backup-$(date +%F).db
Если план меню не отображает рецепты (пустые слоты при том, что рецепты есть в базе) — почти всегда дело в неверной привязке к группе (group) или домохозяйству (household), если у вас настроено несколько households на одном инстансе. Проверьте, что рецепт и план меню принадлежат одной и той же группе в разделе администрирования.
HTTPS, обратный прокси и проблемы с загрузкой изображений
Mealie активно работает с изображениями рецептов (загрузка, генерация превью), и через обратный прокси это частый источник ошибок 413 (Request Entity Too Large) или битых миниатюр.
Если стоит Nginx перед Mealie, добавьте лимит на размер тела запроса:
server {
listen 443 ssl;
server_name recipes.example.com;
client_max_body_size 20M;
location / {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Если используете Caddy — он по умолчанию не режет тело запроса, но проверьте, что переменная BASE_URL в .env Mealie совпадает с реальным внешним доменом, иначе ссылки на изображения в интерфейсе будут генерироваться с неверным хостом и картинки просто не загрузятся в браузере. Подробный разбор настройки автоматического HTTPS на сервере есть в статье про Caddy с авто-SSL — большинство описанных там паттернов применимо и к Mealie.
Ещё один нюанс: если Mealie стоит за Traefik и вы используете middleware для сжатия или кэширования статики, изображения рецептов (особенно WebP, который Mealie генерирует сам) иногда режутся неправильными заголовками Content-Type. Если сталкивались с похожими проблемами прокси-слоя, посмотрите статью про Traefik на сервере — там разобраны похожие кейсы с некорректными заголовками при проксировании статики.
Резервное копирование и перенос на новый сервер
Отдельная больная тема — перенос Mealie между серверами (например, при смене тарифа или переезде на более мощный VPS). Встроенный бэкап Mealie архивирует базу и загруженные изображения в один zip, но не переносит настройки окружения — секретный ключ SECRET, ключи API интеграций, конфиг SMTP для уведомлений — их нужно переносить отдельно вручную из .env.
Общая последовательность переноса:
# на старом сервере
docker compose exec mealie mealie backup create
# скопировать архив бэкапа и .env
scp -r user@old-server:/opt/mealie/data/backups ./
scp user@old-server:/opt/mealie/.env ./
# на новом сервере — поднять пустой Mealie, затем импортировать бэкап через UI
# Settings → Backups → Upload → Restore
Если данных volume немного, проще и надёжнее скопировать весь каталог с данными напрямую через rsync, не полагаясь на встроенный экспорт:
rsync -avz --progress /opt/mealie/mealie-data/ user@new-server:/opt/mealie/mealie-data/
Для регулярного автоматического бэкапа volume на VPS в целом (не только Mealie) есть отдельный разбор в статье про бэкап Docker volume на сервере — стоит настроить это один раз и не думать о переносе данных при следующем обновлении или миграции сервера.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Mealie требует много ресурсов на VPS?
Нет, для базового использования (сотня-другая рецептов, один-два пользователя) достаточно 1-2 ГБ RAM и 1 vCPU. Ресурсы начинают ощутимо расти при включении ИИ-распознавания рецептов по фото или при базе на несколько тысяч записей — тогда лучше закладывать 2-4 ГБ.
Можно ли использовать Mealie без Docker?
Технически да, есть возможность собрать из исходников (backend на Python/FastAPI, frontend на Nuxt), но в реальной эксплуатации это сильно усложняет обновления и почти никто так не делает — Docker Compose остаётся стандартным и наименее проблемным способом деплоя.
Почему после переноса на новый сервер пропали пользователи?
Обычно потому что при переносе скопировали только каталог с изображениями рецептов, а не всю базу данных (SQLite-файл или Postgres volume целиком). Пользователи, группы и рецепты хранятся в базе, а не в файловой структуре — переносить нужно оба компонента.
Как часто нужно делать бэкап?
Как минимум перед каждым обновлением версии образа — миграции схемы базы иногда идут не гладко. Для активно используемой базы рецептов имеет смысл настроить автоматический ежедневный бэкап через cron с ротацией на 7-14 дней.
Mealie можно развернуть с несколькими пользователями и разными правами?
Да, начиная с концепции households/groups в интерфейсе можно организовать несколько независимых наборов рецептов на одном инстансе — удобно для семьи с раздельными списками покупок или для нескольких небольших команд на одном сервере.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →