SSD Nodes Learn 🎉 VPS від $5.50/міс
Посібники Matt ConnorВід Matt Connor · Оновлено 2026-08-13

Mealie на VPS: встановлення через Docker Compose

Розгорніть Mealie на власному VPS через Docker Compose: імпортуйте рецепт за посиланням, створюйте плани харчування та списки покупок, налаштуйте nginx, TLS і резервні копії.

Що робить self-hosted менеджер рецептів

Self-hosted менеджер рецептів зберігає ваші рецепти в базі даних на сервері, який належить вам. У більшості домогосподарств для цього обирають Mealie. Ви вставляєте адресу сторінки з рецептом, а Mealie зчитує з неї інгредієнти, етапи приготування, кількість порцій і час приготування, відкидаючи опис та рекламу. У вашій колекції залишається сам рецепт.

Решта застосунку невелика. Є тижневий план харчування, до якого можна перетягувати рецепти, і список покупок, сформований на основі цього плану. Кожна людина, яка готує, отримує власний обліковий запис. Усе працює в одному контейнері та простоює між запитами, тому помірний VPS працює з ним без помітного навантаження.

У цьому посібнику використовується Docker Compose. Якщо терміни services: і volumes: вам незнайомі, спочатку прочитайте як влаштовані файли Docker Compose, оскільки все нижче — це один compose-файл і чотири команди.

Встановлення Mealie за допомогою Docker Compose

Mealie публікує свої образи в реєстрі контейнерів GitHub. Станом на липень 2026 року поточний стабільний тег — v3.22.0. Зафіксуйте версію замість використання latest: з latest у будь-який день може вийти docker compose pull, який перенесе вас через міграцію бази даних, до якої ви ще не готові.

sudo mkdir -p /srv/mealie
cd /srv/mealie
sudo nano docker-compose.yml
services:
  mealie:
    image: ghcr.io/mealie-recipes/mealie:v3.22.0
    container_name: mealie
    restart: always
    ports:
      - "127.0.0.1:9925:9000"
    deploy:
      resources:
        limits:
          memory: 1000M
    volumes:
      - mealie-data:/app/data/
    environment:
      ALLOW_SIGNUP: "false"
      PUID: 1000
      PGID: 1000
      TZ: Europe/Amsterdam
      BASE_URL: https://recipes.example.com

volumes:
  mealie-data:

Перед запуском варто звернути увагу на два рядки.

Порт записано як 127.0.0.1:9925:9000, а не як 9925:9000. Усередині контейнер слухає порт 9000, а хост перенаправляє на нього порт 9925. Прив’язка цього відображення до loopback-адреси означає, що nginx може звертатися до Mealie, а інтернет — ні. Docker додає власні правила до packet filter, тому звичайний 9925:9000 доступний ззовні, навіть якщо firewall повідомляє, що порт закритий. Це варто зрозуміти один раз: див. чому опубліковані порти Docker ігнорують ufw.

BASE_URL має містити точну публічну адресу, яку ви використовуватимете, зі scheme і без кінцевого слеша. Mealie формує за нею посилання для скидання пароля та запрошень. Якщо встановити http://localhost:9925, запрошення, яке ви надішлете партнеру, міститиме посилання, що працює лише на самому сервері.

Запустіть сервіс і відстежуйте перший запуск.

sudo docker compose up -d
sudo docker compose logs -f mealie

Під час першого запуску створюється база даних SQLite і виконуються міграції. Це займає кілька секунд. Коли журнал стабілізується і рядки міграцій перестануть з’являтися, перевірте застосунок локально.

curl -I http://127.0.0.1:9925

Відповідь 200 OK означає, що застосунок працює. Відповідь Connection refused означає, що контейнер не запущений: виконайте sudo docker compose ps і перевірте код завершення. Контейнер, який завершився з кодом 137, було примусово зупинено через перевищення ліміту пам’яті 1000M. Це трапляється на найдешевших тарифах.

Перший вхід і вимкнення відкритої реєстрації

Обліковий запис за замовчуванням — changeme@example.com, пароль — MyPassword. Увійдіть за допомогою цих даних, а потім негайно змініть їх обидва, оскільки цю пару надруковано в документації, а отже, її знає кожен сканер.

ALLOW_SIGNUP: "false" у compose-файлі встановлено навмисно. Якщо реєстрацію відкрито, будь-хто, хто знайде адресу, може створити обліковий запис у вашому сховищі рецептів. Якщо реєстрацію закрито, ви додаєте користувачів в адміністративній області. Після цього система створює посилання-запрошення, яке ви надсилаєте їм самостійно. Це посилання формується на основі BASE_URL, тому це значення має значення. Якщо ви запустите кілька застосунків на одному сервері й захочете використовувати один пароль для всіх, Mealie може передавати автентифікацію зовнішньому постачальнику ідентифікації, наприклад самостійно розгорнутому екземпляру Authentik.

Mealie об’єднує користувачів у домогосподарство. Усі користувачі одного домогосподарства спільно використовують колекцію рецептів, план харчування та список покупок. Це підходить для сім’ї. Окремі домогосподарства на одному сервері мають окремі колекції. Це зручно для спільного житла, де ніхто не може дійти згоди щодо анчоусів.

Імпортер — причина його запуску

Відкрийте колекцію рецептів, виберіть створення рецепта з URL і вставте посилання. Mealie завантажить сторінку та шукатиме структуровані дані рецепта — блок у машиночитному форматі, який більшість сайтів з рецептами вбудовує для пошукових систем. Якщо цей блок присутній, імпорт виконується коректно й одразу.

Також можна імпортувати рецепт із зображення або вставленого звичайного тексту. Це дає змогу обробляти фотографію сторінки з кулінарної книги. Такий імпорт виконується повільніше й потребує перевірки після завершення, оскільки рукописний дріб легко прочитати неправильно.

Масовий імпорт запускається з того самого екрана: вставте список адрес, по одній у кожному рядку, і Mealie обробить їх у фоновому режимі. Колекцію з двохсот закладок можна імпортувати за один сеанс.

Плани харчування та список покупок

Планувальник харчування — це календар. Перетягніть рецепт на потрібний день, і його буде заплановано. Після цього список покупок збирає інгредієнти із запланованих рецептів в один список і об’єднує дублікати. Тому двом рецептам, для яких потрібна цибуля, відповідає один рядок, а не два.

У магазині список відкритий на телефоні як актуальна сторінка. Оскільки його зберігає ваш власний сервер, усі члени домогосподарства одночасно бачать той самий список. Якщо одна людина позначає молоко як придбане, воно зникає з екрана іншої людини.

Налаштуйте nginx і TLS перед застосунком

Mealie працює через звичайний HTTP і не має власних засобів роботи із сертифікатами. Завершуйте TLS у nginx, розміщеному перед Mealie. Спочатку додайте DNS-запис A для сервера, оскільки під час отримання сертифіката перевіряється це ім’я.

sudo apt update && sudo apt install -y nginx
sudo nano /etc/nginx/sites-available/mealie
server {
    listen 80;
    server_name recipes.example.com;

    client_max_body_size 64M;

    location / {
        proxy_pass http://127.0.0.1:9925;
        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;
    }
}
sudo ln -s /etc/nginx/sites-available/mealie /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Виведення nginx -t, syntax is ok і test is successful підтверджує коректність конфігурації. Виконуйте перезавантаження лише після успішної перевірки. Якщо конфігурація має помилки, після перезавантаження nginx продовжить працювати зі старою конфігурацією, а помилка стане помітною лише під час наступного запуску.

client_max_body_size 64M потрібен, оскільки стандартне значення nginx становить 1 MB. Завантаження фотографії рецепта або відновлення резервної копії через браузер передає тіло запиту більшого розміру. Без цього рядка nginx повертає 413 Request Entity Too Large, а не Mealie, тому в журналі застосунку взагалі не буде відповідного запису.

Після цього отримайте сертифікат. Цей крок і таймер його поновлення описано в розділі отримання сертифіката Let's Encrypt для nginx за допомогою certbot.

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d recipes.example.com

Certbot змінює server block, щоб він прослуховував порт 443, і додає перенаправлення з порту 80. Відкрийте сайт через https:// і переконайтеся, що браузер приймає сертифікат. Якщо Mealie завантажується, але його власні посилання перенаправляють вас на http://, параметр BASE_URL досі має значення http. Виправте його, а потім виконайте sudo docker compose up -d, щоб повторно створити контейнер із новим значенням.

Розміщення Mealie у підшляху, наприклад example.com/recipes, не працює, оскільки frontend не може працювати з підшляху. Використовуйте піддомен.

Резервні копії та що насправді робить відновлення

Усе, чим володіє Mealie, зберігається в /app/data/ усередині контейнера. Це том mealie-data. Скопіюйте цей том — і ви одночасно скопіюєте рецепти, зображення та базу даних.

sudo docker volume ls
sudo docker compose stop mealie
sudo docker run --rm -v mealie_mealie-data:/data -v "$PWD":/backup \
  alpine tar czf /backup/mealie-data.tgz -C /data .
sudo docker compose start mealie

Назва тому містить назву проєкту як префікс, а назва проєкту — це ім’я каталогу, у якому розміщено файл compose. У /srv/mealie том має назву mealie_mealie-data, тому першою командою є docker volume ls: використовуйте назву, яку вона виводить, а не назву з цього посібника. Спочатку потрібно зупинити контейнер, оскільки SQLite часто виконує запис, і копія активної бази може виявитися непридатною для читання після відновлення.

У Mealie також є власна сторінка резервного копіювання в адміністративній області. Вона створює переносний архів, у якому база даних зберігається у форматі JSON разом із зображеннями. Використовуйте цей спосіб для перенесення між серверами, оскільки він краще переносить зміну версії, ніж копіювання необробленого файла. Відновлення архіву навмисно є деструктивною операцією: поточна база даних видаляється перед завантаженням архіву, і скасувати цю операцію неможливо. Після завершення ви вийдете із системи.

Жодна з цих копій не є резервною, якщо вона зберігається на тому самому сервері. За розкладом передавайте архів в інше місце. Для цього призначені зашифровані резервні копії на іншому сервері за допомогою restic.

Оновлення Mealie

cd /srv/mealie
sudo nano docker-compose.yml
sudo docker compose pull
sudo docker compose up -d
sudo docker compose logs -f mealie

Змініть зафіксовану версію у файлі, потім завантажте новий образ і повторно створіть контейнер. Міграції виконуються під час першого запуску нового образу. Перед переходом на нову основну версію створіть копію тому, оскільки міграція, яка завершилася помилкою на півдорозі, може залишити базу даних, яку попередній образ більше не відкриє. Ознайомтеся з нотатками до випусків для всіх версій між поточною та новою.

Якщо імпорт не вдається

Деякі сайти взагалі не публікують структуровані дані рецептів, тому Mealie імпортує назву з порожнім списком інгредієнтів. Це не можна виправити налаштуванням. У такому разі вставте текст рецепта вручну.

Інші помилки спричинені захистом від ботів перед сайтом із рецептами. Замість рецепта цей захист повертає Mealie сторінку перевірки. Mealie вже імітує браузер і змінює user agent, щоб зменшити кількість таких випадків. Якщо сайт усе одно відхиляє запит, у документації наведено два варіанти: спрямувати scraper через proxy з кращою репутацією IP-адреси або запустити екземпляр FlareSolverr, який проходить перевірку у звичайному браузері. Обидва варіанти необов’язкові. Обидва налаштовуються через змінні середовища контейнера.

Якщо імпорт не вдається через те, що сервер взагалі не може підключитися до сайту, це інша проблема. Перевірте підключення із сервера за допомогою curl -I https://the-site.example/recipe і прочитайте рядок зі статусом, перш ніж звинувачувати scraper.

Де це доречно

Mealie — вдалий перший self-hosted застосунок для домашнього використання, оскільки люди, з якими ви живете, користуватимуться ним без додаткових нагадувань. За призначенням він подібний до власної фототеки з Immich, але значно легший, і належить до ширшого переліку речей, які варто self-hosted розмістити цього року. Один невеликий сервер може розміщувати обидва застосунки. Immich — не єдиний кандидат для другого завдання. Якщо ви ще обираєте, вимоги до обсягу пам’яті та команди резервного копіювання PhotoPrism і Immich достатньо відрізняються, щоб ознайомитися з ними, перш ніж віддати решту дискового простору.

FAQ

Чому не вдається імпортувати URL рецепта?

Є дві поширені причини. Або сторінка не містить структурованих даних рецепта, тому scraper не знаходить потрібної інформації, і ви отримуєте лише назву без інгредієнтів, або захисний шар від ботів перед сайтом повертає сторінку перевірки замість рецепта. У другому випадку Mealie можна спрямувати через proxy з кращою репутацією адреси або на self-hosted екземпляр FlareSolverr, який проходить перевірку в реальному браузері. Перш ніж щось змінювати, переконайтеся за допомогою curl -I, що ваш сервер узагалі може отримати доступ до сторінки.

Чи потрібен PostgreSQL, чи достатньо SQLite?

Для домашнього використання достатньо SQLite, і саме його вибрано за замовчуванням. Перейдіть на PostgreSQL, якщо каталог даних розташований у network attached storage, оскільки SQLite у мережевій файловій системі спричиняє помилки блокування бази даних і може пошкодити файл. Для відновлення в PostgreSQL користувач бази даних має бути superuser, оскільки під час відновлення всі дані видаляються перед завантаженням архіву.

Чи можна запустити Mealie без доменного імені?

Так, у власній мережі. Установіть BASE_URL на адресу, яку ви фактично вводитимете, наприклад http://192.168.1.20:9925, і не налаштовуйте nginx. Посилання для запрошень і скидання пароля формуються на основі BASE_URL, тому неправильне значення створить посилання, які ніхто інший не зможе відкрити. Не відкривайте доступ до сервісу через інтернет із використанням звичайного HTTP, оскільки в такому разі облікові дані надсилаються у відкритому вигляді.

Як надати членам сім’ї окремі облікові записи?

Залиште ALLOW_SIGNUP зі значенням "false" і додайте користувачів в адміністративному розділі. Після цього буде створено посилання-запрошення, яке можна їм надіслати. Додайте всіх, хто користується однією кухнею, до одного household, щоб вони мали спільний доступ до рецептів, плану харчування та списку покупок. Окремі household на одному сервері зберігають окремі колекції.

Що станеться з моїми рецептами, якщо я припиню використовувати Mealie?

Ви зможете їх забрати. Резервна копія з адміністративного розділу зберігає ваші дані у форматі JSON. Mealie також може експортувати рецепти як звичайні markdown-файли, які можна читати в будь-якому текстовому редакторі без додаткового програмного забезпечення. Створіть експорт заздалегідь і перевірте, що можете його відкрити.