SSD Nodes Learn Hosting plans →
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-08-28

VPS पर Mealie कैसे इंस्टॉल करें: Docker Compose गाइड

अपने VPS पर Mealie को Docker Compose के साथ सेटअप करना सीखें। यह गाइड आपको रेसिपी इंपोर्ट, मील प्लान, शॉपिंग लिस्ट और Nginx के साथ सुरक्षित TLS कॉन्फ़िगरेशन सेटअप करने में मदद करेगी।

Self-hosted recipe manager क्या करता है

एक self-hosted recipe manager आपकी recipes को आपके अपने सर्वर पर स्थित database में सुरक्षित रखता है, और Mealie वह विकल्प है जिसे अधिकांश घरों में पसंद किया जाता है। आप किसी recipe पेज का address paste करते हैं और Mealie उसमें से सामग्री (ingredients), चरण (steps), मात्रा (yield) और पकाने का समय (cook time) निकाल लेता है, और बाकी की कहानी व विज्ञापनों को हटा देता है। आपके collection में केवल भोजन संबंधी जानकारी ही बचती है।

App का बाकी हिस्सा छोटा है। इसमें एक साप्ताहिक meal plan है जिसमें आप recipes को drag कर सकते हैं, और उस plan से बनी एक shopping list भी है। खाना बनाने वाले प्रत्येक व्यक्ति का अपना login होता है। यह सब एक container में चलता है, और requests के बीच यह idle रहता है, इसलिए एक साधारण VPS इसे बिना किसी भार के चला सकता है।

यह guide Docker Compose का उपयोग करती है। यदि services: और volumes: शब्द आपके लिए नए हैं, तो पहले Docker Compose files कैसे बनाई जाती हैं पढ़ें, क्योंकि नीचे दी गई पूरी प्रक्रिया एक compose file और चार commands पर आधारित है।

Docker Compose के साथ Mealie इंस्टॉल करें

Mealie अपनी images को GitHub container registry पर publish करता है। जुलाई 2026 तक, वर्तमान stable tag v3.22.0 है। latest का उपयोग करने के बजाय एक version को pin करें: latest के साथ, किसी असंबंधित दिन पर होने वाला docker compose pull आपको ऐसे database migration पर ले जा सकता है जिसके लिए आप तैयार नहीं थे।

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:

इसे शुरू करने से पहले दो पंक्तियों पर ध्यान देना आवश्यक है।

Port को 127.0.0.1:9925:9000 के रूप में लिखा गया है, न कि 9925:9000 के रूप में। Container अंदर 9000 पर listen करता है, और host इसे 9925 पर map करता है। उस map को loopback address से bind करने का अर्थ है कि Nginx, Mealie तक पहुँच सकता है लेकिन इंटरनेट नहीं। Docker अपने स्वयं के rules को packet filter में लिखता है, इसलिए एक साधारण 9925:9000 बाहर से तब भी पहुँच योग्य होता है जब आपका firewall कहता है कि port बंद है। यह आश्चर्य एक बार समझने लायक है: Docker द्वारा publish किए गए ports ufw को क्यों अनदेखा करते हैं देखें।

BASE_URL वह सटीक public address होना चाहिए जिसका आप उपयोग करेंगे, जिसमें scheme हो और अंत में कोई slash न हो। Mealie इससे password reset links और invitation links बनाता है। यदि आप इसे http://localhost:9925 पर set करते हैं, तो आपके द्वारा अपने partner को भेजा गया invitation एक ऐसा link रखेगा जो केवल server पर ही काम करेगा।

इसे शुरू करें और पहली boot प्रक्रिया को देखें।

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

पहली बार शुरू करने पर SQLite database बनता है और migrations चलते हैं, जिसमें कुछ सेकंड लगते हैं। जब log स्थिर हो जाए और migration lines print करना बंद कर दे, तो app को स्थानीय रूप से जाँचे।

curl -I http://127.0.0.1:9925

200 OK का अर्थ है कि app चल रहा है। Connection refused का अर्थ है कि container नहीं चल रहा है: sudo docker compose ps चलाएँ और exit code पढ़ें। जो container code 137 के साथ बंद हुआ, उसे 1000M memory limit पार करने के कारण kill कर दिया गया था, जो सबसे छोटे plans पर होता है।

पहली बार लॉगिन करना और ओपन साइनअप बंद करना

डिफ़ॉल्ट अकाउंट changeme@example.com है और इसका पासवर्ड MyPassword है। इससे लॉगिन करें और तुरंत दोनों को बदल दें, क्योंकि यह जानकारी डॉक्यूमेंटेशन में दी गई है और सभी स्कैनर्स में मौजूद है।

कंपोज़ फ़ाइल में ALLOW_SIGNUP: "false" जानबूझकर रखा गया है। यदि साइनअप खुला है, तो कोई भी व्यक्ति जो आपका पता ढूंढ लेता है, वह आपके रेसिपी बॉक्स में अकाउंट बना सकता है। इसे बंद रखने पर, आप एडमिन एरिया से लोगों को जोड़ते हैं, जो एक इनविटेशन लिंक बनाता है जिसे आप स्वयं उन्हें भेजते हैं। वह लिंक BASE_URL से बनता है, इसीलिए यह वैल्यू महत्वपूर्ण है। यदि आप एक ही सर्वर पर कई ऐप्स चला रहे हैं और उन सभी के लिए एक ही पासवर्ड चाहते हैं, तो Mealie अपने लॉगिन को किसी बाहरी आइडेंटिटी प्रोवाइडर जैसे कि सेल्फ-होस्टेड Authentik इंस्टेंस को सौंप सकता है।

Mealie उपयोगकर्ताओं को एक हाउसहोल्ड (परिवार) में समूहित करता है। एक हाउसहोल्ड के सभी सदस्य रेसिपी कलेक्शन, मील प्लान और शॉपिंग लिस्ट साझा करते हैं, जो कि एक परिवार की आवश्यकता होती है। एक ही सर्वर पर अलग-अलग हाउसहोल्ड अपने कलेक्शन अलग रखते हैं, जो कि फ्लैटशेयर के लिए उपयुक्त है जब लोग किसी चीज़ पर सहमत न हों।

इंपोर्टर, जिसे चलाने का मुख्य कारण

Recipe collection खोलें, URL से recipe बनाने का विकल्प चुनें और लिंक पेस्ट करें। Mealie पेज को फेच करता है और structured recipe data की तलाश करता है, जो कि वह machine-readable ब्लॉक है जिसे अधिकांश recipe साइटें सर्च इंजन के लिए एम्बेड करती हैं। जब वह ब्लॉक मौजूद होता है, तो इंपोर्ट साफ और तुरंत हो जाता है।

आप किसी इमेज या प्लेन टेक्स्ट को पेस्ट करके भी इंपोर्ट कर सकते हैं, जो कि कुकबुक के किसी पेज की फोटो के लिए उपयोगी है। ये एक धीमी प्रक्रिया से गुजरते हैं और बाद में जांच की मांग करते हैं, क्योंकि हाथ से लिखे गए fractions को गलत पढ़ना आसान होता है।

Bulk imports उसी स्क्रीन से चलते हैं: पतों की एक सूची पेस्ट करें, प्रति लाइन एक, और Mealie बैकग्राउंड में उन पर काम करता है। दो सौ बुकमार्क का संग्रह एक बार में ही ट्रांसफर हो जाता है।

Meal plans और shopping list

Meal planner एक calendar है। किसी recipe को drag करके किसी दिन पर रखें, वह plan हो जाएगी। इसके बाद shopping list, planned recipes की सामग्री को एक सूची में इकट्ठा करती है और duplicates को मिला देती है। उदाहरण के लिए, यदि दो recipes में प्याज की आवश्यकता है, तो सूची में दो के बजाय एक ही line दिखाई देगी।

दुकान पर यह सूची आपके phone पर एक live page की तरह काम करती है। चूंकि इसे आपका अपना server host करता है, इसलिए घर का हर सदस्य एक ही समय पर एक ही सूची देख सकता है। यदि कोई एक व्यक्ति milk को tick करके हटाता है, तो वह दूसरे व्यक्ति की screen से भी हट जाता है।

Nginx और TLS को सामने रखें

Mealie केवल plain HTTP का उपयोग करता है और इसमें स्वयं का कोई certificate handling नहीं है। इसके सामने nginx में transport layer security (TLS) को terminate करें। सबसे पहले अपने सर्वर पर एक DNS A record point करें, क्योंकि certificate step उस नाम को verify करता है।

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 को print करना और syntax is ok तथा test is successful का उपयोग करना ही मुख्य द्वार है। केवल तभी reload करें जब यह सफल हो जाए, क्योंकि खराब configuration को reload करने पर पुरानी configuration ही चलती रहती है और अगली बार restart होने तक गलती का पता नहीं चलता।

client_max_body_size 64M यहाँ इसलिए है क्योंकि nginx का default मान 1 MB है। browser के माध्यम से recipe की photo upload करने या backup restore करने पर इससे बड़ी file भेजी जाती है, और इस line के बिना आपको nginx से 413 Request Entity Too Large error मिलता है, न कि Mealie से, इसलिए application log में कुछ भी दिखाई नहीं देता।

इसके बाद certificate जारी करें। उस step और उसके renewal timer के बारे में certbot के साथ nginx के लिए Let's Encrypt certificate जारी करना में बताया गया है।

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

Certbot server block को 443 port पर listen करने के लिए rewrite करता है और port 80 से एक redirect जोड़ता है। site को https:// पर load करें और पुष्टि करें कि browser certificate को स्वीकार करता है। यदि Mealie load हो जाता है लेकिन उसके links आपको http:// पर भेजते हैं, तो इसका मतलब है कि BASE_URL में अभी भी http लिखा है जिसे ठीक करने की आवश्यकता है, और उसके बाद नए value के साथ container को फिर से बनाने के लिए sudo docker compose up -d चलाएं।

Mealie को example.com/recipes जैसे subpath के अंतर्गत serve करना काम नहीं करता है, क्योंकि frontend को subpath से serve नहीं किया जा सकता है। एक subdomain का उपयोग करें।

बैकअप, और रिस्टोर वास्तव में क्या करता है

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 के रूप में एक पोर्टेबल आर्काइव में लिखता है। सर्वर बदलने के लिए इसका उपयोग करें, क्योंकि यह वर्जन बदलने पर भी सुरक्षित रहता है, जबकि रॉ फाइल कॉपी शायद न रहे। एक को रिस्टोर करना जानबूझकर विनाशकारी बनाया गया है: यह आर्काइव लोड करने से पहले वर्तमान डेटाबेस को डिलीट कर देता है, और इसे अनडू (undo) नहीं किया जा सकता। प्रक्रिया पूरी होने पर आप लॉग आउट हो जाएंगे।

जब तक कॉपी उसी सर्वर पर रहती है, तब तक वह बैकअप नहीं है। आर्काइव को शेड्यूल के अनुसार कहीं और भेजें, जिसके लिए 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

फाइल में पिन किए गए version को बढ़ाएं, फिर pull करें और recreate करें। नए image के पहली बार start होने पर migrations अपने आप चलते हैं। major version change से पहले volume की एक copy बना लें, क्योंकि यदि migration बीच में विफल हो जाता है, तो database ऐसी स्थिति में रह जाता है जिसे पिछला image फिर से नहीं खोल पाएगा। अपने वर्तमान version और नए version के बीच के सभी release notes को ध्यान से पढ़ें।

जब इम्पोर्टर विफल हो जाता है

कुछ साइटें कोई भी स्ट्रक्चर्ड रेसिपी डेटा पब्लिश नहीं करती हैं, और ऐसी स्थिति में Mealie खाली सामग्री सूची (ingredient list) के साथ केवल शीर्षक इम्पोर्ट करता है। इसे किसी कॉन्फ़िगरेशन द्वारा ठीक नहीं किया जा सकता है। इसके बजाय रेसिपी टेक्स्ट को मैन्युअल रूप से पेस्ट करें।

अन्य विफलताएं रेसिपी साइट के सामने मौजूद बॉट प्रोटेक्शन के कारण होती हैं, जो Mealie को रेसिपी के बजाय एक चैलेंज पेज भेजती है। Mealie पहले से ही एक ब्राउज़र का रूप धारण करता है और इसे कम करने के लिए अपने user agent को रोटेट करता है। जब कोई साइट फिर भी मना कर देती है, तो इसके लिए उपलब्ध विकल्प यह हैं कि स्क्रैपर को बेहतर एड्रेस रेपुटेशन वाले प्रॉक्सी के माध्यम से भेजा जाए, या एक FlareSolverr इंस्टेंस चलाया जाए जो वास्तविक ब्राउज़र में चैलेंज को हल करता है। ये दोनों विकल्प वैकल्पिक हैं, और दोनों को कंटेनर पर environment variables के माध्यम से सेट किया जाता है।

यदि इम्पोर्ट इसलिए विफल होता है क्योंकि आपका सर्वर साइट तक बिल्कुल नहीं पहुँच पा रहा है, तो यह एक अलग समस्या है। स्क्रैपर को दोष देने से पहले, बॉक्स से curl -I https://the-site.example/recipe के साथ इसका परीक्षण करें और स्टेटस लाइन को पढ़ें।

यह कहाँ फिट बैठता है

Mealie किसी household के लिए एक अच्छा पहला self-hosted application है, क्योंकि आपके साथ रहने वाले लोग इसे बिना कहे उपयोग करेंगे। इसका काम Immich के साथ अपनी photo library चलाने जैसा ही है, हालांकि यह काफी हल्का है, और यह इस वर्ष self-host करने योग्य चीजों की विस्तृत सूची में शामिल है। एक छोटा server दोनों को चला सकता है। उस दूसरे काम के लिए Immich ही एकमात्र विकल्प नहीं है। यदि आप अभी भी तय कर रहे हैं, तो PhotoPrism और Immich की memory requirements और backup commands में पर्याप्त अंतर है, इसलिए disk की बाकी जगह किसी अन्य काम के लिए देने से पहले उन्हें पढ़ना उपयोगी होगा। यदि household अपने dinners के साथ plans और notes भी कहीं रखना चाहता है, तो self-hosted AFFiNE workspace फिर से वही compose-file exercise है, लेकिन इसके लिए Mealie की तुलना में चार containers और काफी अधिक memory चाहिए। इसलिए पहले देखें कि box में कितने resources बचे हैं। यदि household अपने dinners के साथ training भी track करना चाहता है, तो openGym workouts को संभालता है और उसी pinned tag, compose file और certificate की मांग करता है, जिन पर आपने अभी काम किया है। Dinner के बाद की शाम के लिए इसका एक अलग रूप है, क्योंकि Halcyon मौजूदा Jellyfin library को 1990s की ऐसी rental shop में बदल देता है जिसमें आप घूम सकते हैं। यह किसी पहले से चल रही service के सामने एक और छोटा container जोड़ता है, न कि backup के लिए एक और database। इस समूह की हर चीज household app नहीं है। यदि यही आदत कभी work के लिए भी कुछ संभालने लगे, तो self-hosted Chatwoot support desk फिर से वही pinned tag और certificate इस्तेमाल करता है, लेकिन इसके पीछे Postgres, Redis और काम करने वाला outbound mail चाहिए। यह recipe box की तुलना में काफी भारी tenant है और इसके लिए अपना server होना चाहिए।

FAQ

रेसिपी URL इम्पोर्ट करना विफल क्यों हो जाता है?

इसके दो सामान्य कारण हैं। या तो पेज पर कोई स्ट्रक्चर्ड रेसिपी डेटा पब्लिश नहीं किया गया है, इसलिए स्क्रैपर को कुछ नहीं मिलता और आपको बिना सामग्री (ingredients) वाला केवल एक शीर्षक मिलता है, या साइट के सामने मौजूद बॉट-प्रोटेक्शन लेयर रेसिपी के बजाय एक चैलेंज पेज दिखाती है। दूसरे मामले के लिए, Mealie को बेहतर एड्रेस रेपुटेशन वाले प्रॉक्सी, या FlareSolverr के self-hosted इंस्टेंस पर पॉइंट किया जा सकता है, जो वास्तविक ब्राउज़र में चैलेंज को हल करता है। कुछ भी बदलने से पहले यह सुनिश्चित करें कि आपका सर्वर curl -I के साथ उस पेज तक पहुँच सकता है।

क्या मुझे PostgreSQL की आवश्यकता है, या SQLite पर्याप्त है?

घरेलू उपयोग के लिए SQLite पर्याप्त है और यह डिफ़ॉल्ट विकल्प है। जब डेटा डायरेक्टरी नेटवर्क अटैच्ड स्टोरेज (NAS) पर हो, तब PostgreSQL पर स्विच करें, क्योंकि नेटवर्क फाइलसिस्टम पर SQLite का उपयोग करने से 'locked-database' एरर आ सकते हैं और फाइल करप्ट हो सकती है। PostgreSQL के तहत रिस्टोर करने के लिए डेटाबेस यूजर का सुपरयूज़र होना आवश्यक है, क्योंकि रिस्टोर प्रक्रिया आर्काइव लोड करने से पहले सब कुछ डिलीट कर देती है।

क्या मैं बिना डोमेन नाम के Mealie चला सकता हूँ?

हाँ, अपने नेटवर्क पर। BASE_URL को उस एड्रेस पर सेट करें जिसे आप वास्तव में टाइप करेंगे, जैसे कि http://192.168.1.20:9925, और nginx को छोड़ दें। इनविटेशन और पासवर्ड रीसेट लिंक BASE_URL से बनते हैं, इसलिए गलत वैल्यू होने पर ऐसे लिंक बनेंगे जिन्हें कोई और नहीं खोल पाएगा। इसे प्लेन HTTP के माध्यम से इंटरनेट पर एक्सपोज़ न करें, क्योंकि ऐसा करने पर लॉगिन क्रेडेंशियल्स बिना एन्क्रिप्शन के भेजे जाते हैं।

मैं अपने परिवार के सदस्यों को उनके अपने लॉगिन कैसे दूँ?

ALLOW_SIGNUP को "false" पर सेट रहने दें और एडमिन एरिया से लोगों को जोड़ें, जिससे एक इनविटेशन लिंक जनरेट होगा जिसे आप उन्हें भेज सकते हैं। जो लोग एक ही किचन शेयर करते हैं, उन्हें एक ही 'household' में रखें ताकि वे रेसिपी, मील प्लान और शॉपिंग लिस्ट साझा कर सकें। एक ही सर्वर पर अलग-अलग 'households' रखने से उनके कलेक्शन अलग-अलग रहते हैं।

यदि मैं Mealie चलाना बंद कर दूँ तो मेरी रेसिपी का क्या होगा?

वे सुरक्षित रहती हैं। एडमिन बैकअप आपके डेटा को JSON के रूप में लिखता है, और Mealie रेसिपी को प्लेन markdown फाइलों के रूप में भी एक्सपोर्ट कर सकता है। ये फाइलें किसी भी सॉफ्टवेयर के बिना किसी भी टेक्स्ट एडिटर में पढ़ी जा सकती हैं। आवश्यकता पड़ने से पहले एक एक्सपोर्ट लेकर चेक कर लें कि आप उसे खोल पा रहे हैं।