התקנת Mealie על שרת VPS באמצעות Docker Compose
למדו איך להריץ מנהל מתכונים בניהול עצמי עם Docker Compose. המדריך כולל הגדרת Nginx, תעודות TLS, גיבויים אוטומטיים וטיפים למניעת שגיאות בגרסאות ה-image של Mealie.
מה עושה מנהל מתכונים בניהול עצמי
מנהל מתכונים בניהול עצמי שומר את המתכונים שלכם במסד נתונים על שרת שבבעלותכם, ו־Mealie הוא הפתרון שרוב משקי הבית בוחרים בו. אתם מדביקים את הכתובת של דף המתכון, ו־Mealie מחלץ ממנו את המרכיבים, השלבים, כמות המנות וזמן הבישול, תוך שהוא מסנן את סיפור הרקע והפרסומות. מה שנשאר באוסף שלכם הוא האוכל בלבד.
שאר היישום מצומצם. ישנו תכנון ארוחות שבועי שאליו גוררים מתכונים, ורשימת קניות שנבנית מתוך התוכנית הזו. לכל אדם שמבשל יש שם משתמש וסיסמה משלו. הכל רץ בתוך מכולה (container) אחת, והיא נשארת במצב המתנה בין בקשות, כך שגם שרת VPS צנוע יריץ אותה ללא מאמץ.
מדריך זה משתמש ב־Docker Compose. אם המושגים services: ו־volumes: חדשים לכם, קראו תחילה את איך קובצי Docker Compose בנויים, כיוון שכל מה שמופיע בהמשך מבוסס על קובץ compose אחד וארבע פקודות.
התקנת Mealie באמצעות Docker Compose
Mealie מפרסמת את ה-images שלה ב-GitHub container registry. נכון ליולי 2026, ה-tag היציב העדכני הוא v3.22.0. מומלץ לקבע גרסה (pin) במקום להשתמש ב-latest: עם latest, עדכון docker compose pull ביום לא צפוי עלול להעביר אתכם מיגרציית מסד נתונים שלא הייתם ערוכים אליה.
sudo mkdir -p /srv/mealie
cd /srv/mealie
sudo nano docker-compose.ymlservices:
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 מבפנים, והמארח (host) ממפה אליו את 9925. קישור המיפוי לכתובת ה-loopback מבטיח ש-Nginx יוכל להגיע ל-Mealie, אך האינטרנט לא. Docker כותבת חוקים משלה לתוך ה-packet filter, לכן פורט שפורסם ב-9925:9000 יהיה נגיש מבחוץ גם אם ה-firewall שלכם מוגדר כסגור. כדאי להבין את ההתנהגות הזו פעם אחת: ראו מדוע פורטים של Docker שפורסמו מתעלמים מ-ufw.
BASE_URL חייב להיות הכתובת הציבורית המדויקת שבה תשתמשו, כולל ה-scheme וללא לוכסן (slash) בסוף. 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 termination ב־Nginx לפניו. תחילה, הפנו רשומת DNS מסוג A לשרת שלכם, שכן שלב הנפקת התעודה מאמת את שם המתחם.
sudo apt update && sudo apt install -y nginx
sudo nano /etc/nginx/sites-available/mealieserver {
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 היא תנאי סף. בצעו טעינה מחדש (reload) רק לאחר שהבדיקה עוברת, שכן טעינה של תצורה שגויה משאירה את התצורה הקודמת פעילה ומסתירה את השגיאה עד לאתחול הבא.
ההגדרה client_max_body_size 64M נחוצה מכיוון שברירת המחדל של Nginx היא 1 MB. העלאת תמונת מתכון או שחזור גיבוי דרך הדפדפן שולחים גוף בקשה גדול יותר, ובלי שורה זו תקבלו שגיאת 413 Request Entity Too Large מ־Nginx, ולא מ־Mealie, כך שיומן היישום לא יציג דבר.
לאחר מכן, הנפיקו את התעודה. שלב זה וטיימר החידוש שלו מפורטים בהנפקת תעודת Let's Encrypt עבור Nginx באמצעות certbot.
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d recipes.example.comCertbot משכתב את בלוק ה־server כדי להאזין בפורט 443 ומוסיף הפניה מפורט 80. טענו את האתר דרך https:// וודאו שהדפדפן מקבל את התעודה. אם Mealie נטען אך הקישורים הפנימיים שלו מפנים אתכם ל־http://, סימן ש־BASE_URL עדיין מוגדר כ־http ויש לתקן זאת, ולאחר מכן להריץ sudo docker compose up -d כדי ליצור מחדש את המכולה עם הערך המעודכן.
הגשת Mealie תחת נתיב משנה (subpath) כמו example.com/recipes אינה עובדת, מכיוון שלא ניתן להגיש את ה־frontend מנתיב משנה. השתמשו ב־subdomain.
גיבויים, ומה המשמעות האמיתית של שחזור
כל המידע של Mealie נמצא בתוך /app/data/ בתוך המכולה, שהוא ה-volume המוגדר כ-mealie-data. העתקה של ה-volume הזה משמעותה העתקה של המתכונים, התמונות ומסד הנתונים יחד.
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שם ה-volume כולל את שם הפרויקט כתחילית, ושם הפרויקט הוא שם הספרייה שבה נמצא קובץ ה-compose. מתוך /srv/mealie ה-volume הוא 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עדכנו את גרסת ה-pinned בקובץ, ולאחר מכן בצעו pull והפעלה מחדש של המכולה. תהליכי ה-migration ירוצו בהפעלה הראשונה של ה-image החדש. בצעו גיבוי של ה-volume לפני שדרוג גרסה מרכזי, כיוון ש-migration שנכשל באמצע עלול להשאיר את מסד הנתונים במצב שה-image הקודם לא יוכל לפתוח. קראו את ה-release notes עבור כל הגרסאות שבין הגרסה הנוכחית שלכם לבין הגרסה החדשה.
כאשר תהליך הייבוא נכשל
אתרים מסוימים אינם מפרסמים נתוני מתכונים מובנים כלל, ובמקרים אלו Mealie מייבא כותרת עם רשימת רכיבים ריקה. לא ניתן להגדיר פתרון לבעיה זו; במקום זאת, יש להדביק את טקסט המתכון באופן ידני.
כשלים אחרים נובעים ממנגנוני הגנה מפני בוטים המותקנים לפני אתר המתכונים, אשר משיבים ל-Mealie עם דף אתגר (challenge page) במקום עם המתכון. Mealie כבר מתחזה לדפדפן ומחליף את ה-user agent שלו כדי לצמצם תופעה זו. כאשר אתר עדיין מסרב, האפשרויות המתועדות הן ניתוב ה-scraper דרך proxy בעל מוניטין כתובת טוב יותר, או הרצת מופע של FlareSolverr הפותר את האתגר באמצעות דפדפן אמיתי. שתי האפשרויות הן אופציונליות ומוגדרות באמצעות משתני סביבה בקונטיינר.
ייבוא שנכשל משום שהשרת שלכם אינו מצליח להגיע לאתר כלל הוא בעיה מסוג אחר. בדקו את הגישה מהשרת באמצעות curl -I https://the-site.example/recipe וקראו את שורת הסטטוס לפני שתטילו את האשמה על ה-scraper.
היכן זה משתלב
Mealie הוא יישום מצוין להתחלת אירוח עצמי בבית, כיוון שהאנשים שאתם חיים איתם ישתמשו בו ללא צורך בבקשה מיוחדת. מדובר בסוג עבודה דומה להרצת ספריית תמונות עצמאית עם Immich, אם כי מדובר ביישום קל בהרבה, והוא נמצא ברשימה הרחבה של דברים שכדאי לארח באופן עצמאי השנה. שרת אחד קטן יכול להכיל את שניהם. Immich אינו המועמד היחיד למשימה השנייה, ואם אתם עדיין מתלבטים, דרישות הזיכרון ופקודות הגיבוי של PhotoPrism ושל Immich שונות מספיק כדי שיהיה כדאי לקרוא עליהן לפני שתקצו את שארית שטח הדיסק.
FAQ
מדוע ייבוא של כתובת מתכון נכשל?
קיימות שתי סיבות נפוצות לכך. או שהדף אינו מפרסם נתוני מתכון מובנים, ולכן הכלי לא מוצא דבר ומתקבל כותרת ללא מרכיבים, או ששכבת הגנה מפני בוטים לפני האתר מחזירה דף אתגר במקום את המתכון. במקרה השני, ניתן להפנות את Mealie ל-proxy עם מוניטין כתובת טוב יותר, או למופע 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 כדי שישתפו מתכונים, תוכנית ארוחות ורשימת קניות. משקי בית נפרדים על אותו שרת ישמרו על אוספים נפרדים.
מה קורה למתכונים שלי אם אפסיק להריץ את Mealie?
הם נשארים זמינים. הגיבוי של מנהל המערכת כותב את הנתונים שלכם כ-JSON, ו-Mealie יכולה גם לייצא מתכונים כקבצי markdown פשוטים, שניתן לקרוא בכל עורך טקסט ללא צורך בתוכנה כלשהי. בצעו ייצוא אחד לפני שתזדקקו לו וודאו שאתם מצליחים לפתוח אותו.