Rails ऐप डिप्लॉय करें

Rails 7.1 और उसके बाद के वर्ज़न प्रोडक्शन Dockerfile जेनरेट करते हैं, और Lizard उसे बिना बदले बिल्ड करता है: इमेज gems इंस्टॉल करती है, एसेट्स प्रीकंपाइल करती है और हर बार सर्वर शुरू होने पर bin/rails db:prepare चलाती है। RAILS_MASTER_KEY और डेटाबेस URL सेट करें, फिर Rails 8 के लिए lizard up --port 8080 चलाएँ (Thruster के लिए HTTP_PORT=8080 के साथ), और Rails 7.1 व 7.2 के लिए lizard up --port 3000। Dockerfile न होने पर lizardpack पोर्ट 3000 पर एक साधारण Ruby इमेज बिल्ड करता है।

टेस्ट स्टेटस: हमने Rails के जेनरेट किए Dockerfile, bin/docker-entrypoint, config/puma.rb और database.yml, Lizard के बिल्ड और पोर्ट नियम, और Dockerfile के बिना Rails ऐप के लिए lizardpack का प्लान जाँचा है। इस गाइड से अभी तक हमने कोई Rails ऐप शुरू से आख़िर तक डिप्लॉय नहीं किया है।

शुरू करने से पहले

  • Rails 7.1 या उसके बाद का ऐप, जो PostgreSQL (pg gem) इस्तेमाल करता हो और जिसमें जेनरेट किए गए Dockerfile और bin/docker-entrypoint अब भी मौजूद हों। पुराना ऐप इन्हें dockerfile-rails gem से पा सकता है: bundle add dockerfile-rails --group development, फिर bin/rails generate dockerfile।
  • आपके कंप्यूटर पर config/master.key, या ऐप का SECRET_KEY_BASE।
  • ऐसी Gemfile.lock जिसमें x86_64-linux प्लेटफ़ॉर्म शामिल हो। इसे bundle lock --add-platform x86_64-linux से जोड़ें और फ़ाइल कमिट करें।
  • Lizard CLI, lizard login से साइन इन किया हुआ, Pro या 7-दिन के Pro ट्रायल (कार्ड ज़रूरी) पर। प्राइसिंग देखें।

Lizard Rails ऐप को कैसे बिल्ड करता है

आपके ऐप में हैLizard क्या बिल्ड करता हैसर्विस पोर्ट
Rails 8 का Dockerfile (EXPOSE 80, CMD ["./bin/thrust", "./bin/rails", "server"])आपका Dockerfile, बिना बदले8080, HTTP_PORT=8080 के साथ
Rails 7.1 या 7.2 का Dockerfile (EXPOSE 3000)आपका Dockerfile, बिना बदले3000
कोई Dockerfile नहींlizardpack की Ruby इमेज; नीचे देखें3000

सर्विस के बिल्ड और स्टार्ट कमांड खाली छोड़ें। इनमें से कोई भी सेट होने पर Lizard आपका Dockerfile इस्तेमाल करने के बजाय इन कमांड से अपना Dockerfile बनाता है, और उस इमेज में Node.js होता है, Ruby नहीं। स्टार्ट कमांड इमेज के entrypoint की जगह भी ले लेता है, इसलिए db:prepare नहीं चलेगा। बिल्ड का निर्णय-क्रम देखें।

Rails 8 Thruster को शुरू करता है, जो पोर्ट 80 पर सुनता है और अपने पीछे पोर्ट 3000 पर Puma चलाता है। इमेज नॉन-रूट यूज़र (USER 1000:1000) के रूप में चलती है, और नॉन-रूट प्रोसेस को 1024 से नीचे का पोर्ट खोलने की अनुमति शायद न मिले। HTTP_PORT=8080 Thruster को ऐसे पोर्ट पर ले जाता है जिसे वह हमेशा खोल सकता है।

प्रोजेक्ट और डेटाबेस बनाएँ

ऐप की रूट डायरेक्टरी से:

lizard init --name rails-app
lizard add --service web
lizard add postgres

Managed Postgres postgres सुपरयूज़र के रूप में कनेक्ट होता है, इसलिए db:prepare वे डेटाबेस बना सकता है जो Rails माँगता है।

सीक्रेट्स सेट करें और डिप्लॉय करें (Rails 8)

Rails 8 का प्रोडक्शन database.yml चार डेटाबेस परिभाषित करता है: primary, cache, queue और cable। DATABASE_URL सिर्फ़ primary की जगह लेता है। बाकी के लिए Rails CACHE_DATABASE_URL, QUEUE_DATABASE_URL और CABLE_DATABASE_URL पढ़ता है। चारों को एक ही Postgres पर, अलग-अलग डेटाबेस नामों के साथ पॉइंट करें:

PG='postgresql://postgres:${{postgres.PGPASSWORD}}@${{postgres.LIZARD_PRIVATE_DOMAIN}}:5432'
lizard secrets set \
  RAILS_MASTER_KEY="$(cat config/master.key)" \
  DATABASE_URL='${{postgres.DATABASE_PRIVATE_URL}}' \
  CACHE_DATABASE_URL="$PG/rails_cache" \
  QUEUE_DATABASE_URL="$PG/rails_queue" \
  CABLE_DATABASE_URL="$PG/rails_cable" \
  HTTP_PORT=8080 \
  SOLID_QUEUE_IN_PUMA=true \
  --service web
lizard up --service web --port 8080
  • सिंगल कोट्स ${{…}} को आपके शेल से बचाकर रखते हैं। Lizard इन रेफ़रेंस को डिप्लॉय के समय resolve करता है और प्रोजेक्ट का प्राइवेट नेटवर्क इस्तेमाल करता है।
  • SOLID_QUEUE_IN_PUMA=true से Puma ही Solid Queue वर्कर चलाता है, इसलिए Active Job के जॉब वेब सर्विस के अंदर चलते हैं। इसके बिना यह वेब सर्विस कतार में लगे जॉब प्रोसेस नहीं करती।
  • RAILS_MASTER_KEY की जगह SECRET_KEY_BASE तभी इस्तेमाल करें जब ऐप कोई दूसरा एन्क्रिप्टेड क्रेडेंशियल नहीं पढ़ता।

सीक्रेट्स सेट करें और डिप्लॉय करें (Rails 7.1 और 7.2)

ये वर्ज़न एक ही डेटाबेस इस्तेमाल करते हैं:

lizard secrets set \
  RAILS_MASTER_KEY="$(cat config/master.key)" \
  DATABASE_URL='${{postgres.DATABASE_PRIVATE_URL}}' \
  --service web
lizard up --service web --port 3000

हर डिप्लॉय पर क्या होता है

lizard up डायरेक्टरी अपलोड करता है। git रिपॉज़िटरी के अंदर यह वे फ़ाइलें छोड़ देता है जो .gitignore में हैं, और Rails की .gitignore और .dockerignore दोनों config/master.key और .env* फ़ाइलों को बाहर रखती हैं। बिल्ड SECRET_KEY_BASE_DUMMY=1 के साथ एसेट्स प्रीकंपाइल करता है, क्योंकि Lizard Dockerfile बिल्ड को COMMIT_SHA के अलावा कोई वेरिएबल नहीं देता।

स्टार्ट होने पर bin/docker-entrypoint ./bin/rails db:prepare चलाता है: यह न मौजूद डेटाबेस बनाता है, नए डेटाबेस में स्कीमा लोड करता है और बाकी माइग्रेशन चलाता है। यह हर कंटेनर स्टार्ट पर चलता है, रीस्टार्ट पर भी। माइग्रेशन ऐसे रखें कि वे पुराने और नए, दोनों कोड के साथ सुरक्षित रूप से चल सकें।

git push to deploy के लिए ऐप को GitHub पर पुश करें और lizard up चलाने के बजाय रिपॉज़िटरी कनेक्ट करें। वही सीक्रेट्स और पोर्ट (lizard port 8080 --service web) सेट करें। जेनरेट किए गए Dockerfile में bundle install स्टेप है, इसलिए Lizard उसे बिना बदले इस्तेमाल करता है।

जाँचें कि यह काम करता है

lizard logs --build --service web
lizard logs --service web --tail 100
lizard domain --service web

Rails 7.1 और उसके बाद के वर्ज़न ऐप बूट होते ही /up पर HTTP 200 लौटाते हैं। https://<your-domain>/up खोलें, फिर ऐसा पेज खोलें जो डेटाबेस से पढ़ता हो। रनटाइम लॉग में पहले db:prepare का आउटपुट और फिर Puma के शुरू होने की जानकारी दिखनी चाहिए।

Dockerfile के बिना

Gemfile मिलने पर lizardpack Ruby ऐप बिल्ड करता है:

  • Ruby वर्ज़न: .ruby-version, नहीं तो Gemfile की ruby लाइन, नहीं तो 3.4। सिर्फ़ major और minor गिने जाते हैं: 3.4.1 का बिल्ड ruby:3.4-slim पर होता है।
  • यह build-essential और libpq-dev इंस्टॉल करता है, फिर bundle install चलाता है।
  • स्टार्ट: Procfile की web: लाइन, नहीं तो config.ru और Rakefile मौजूद होने पर bundle exec rails server -b 0.0.0.0। पोर्ट 3000।

यह इमेज RAILS_ENV सेट नहीं करती, एसेट्स प्रीकंपाइल नहीं करती और डेटाबेस तैयार नहीं करती, इसलिए यह पूरी Rails साइट के बजाय छोटे ऐप्स और API के लिए बेहतर है। .ruby-version में सिर्फ़ वर्ज़न नंबर लिखें, जैसे 3.4.1। rails new उसमें ruby-3.4.1 लिखता है, और lizardpack इसे ऐसे इमेज नाम में बदल देता है जो मौजूद ही नहीं है। रनटाइम वर्ज़न देखें।

आम समस्याएँ

लक्षणसमाधान
bundle install फ़ेल: बंडल सिर्फ़ दूसरे प्लेटफ़ॉर्म सपोर्ट करता हैbundle lock --add-platform x86_64-linux चलाएँ और Gemfile.lock कमिट करें।
Missing secret_key_base या क्रेडेंशियल्स डिक्रिप्ट नहीं होतेweb सर्विस पर config/master.key से RAILS_MASTER_KEY सेट करें।
cache, queue या cable कनेक्शन /var/run/postgresql जैसे लोकल सॉकेट पर जाता हैCACHE_DATABASE_URL, QUEUE_DATABASE_URL और CABLE_DATABASE_URL सेट करें।
लॉग में पोर्ट 80 के लिए bind: permission denied दिखता हैHTTP_PORT=8080 सेट करें और सर्विस पोर्ट 8080 करें।
डिप्लॉय कभी हेल्दी नहीं होताजाँचें कि सर्विस पोर्ट ऊपर की टेबल से मेल खाता है: lizard port --service web। सर्विस कभी हेल्दी नहीं होती देखें।
जॉब कतार में ही पड़े रहते हैंSOLID_QUEUE_IN_PUMA=true सेट करें। जॉब्स को वेब प्रोसेस से अलग चलाने के लिए dockerfilePath=Dockerfile और startCommand=./bin/jobs के साथ worker मोड में दूसरी सर्विस जोड़ें।
डिप्लॉय के बाद अपलोड की गई फ़ाइलें गायब हो जाती हैंActive Storage की local सर्विस कंटेनर के अंदर लिखती है। amazon सर्विस के साथ S3-कम्पैटिबल Managed Object Storage इस्तेमाल करें।

अगर ऐप Sidekiq या Redis वाला Action Cable एडेप्टर इस्तेमाल करता है, तो Managed Redis जोड़ें और हर उस सर्विस पर REDIS_URL='${{redis.REDIS_PRIVATE_URL}}' सेट करें जिसे इसकी ज़रूरत है।

संबंधित

अपडेट: