सबसे पहले,
इस गाइड के लेखक को धन्यवाद। इसके बिना, मैं इस पोस्ट को लिखने के लिए लंबे समय तक नहीं बैठता था: बहुत सारी समस्याओं को स्वतंत्र रूप से हल करना होगा। हालांकि, मेरे मामले में, स्थिति थोड़ी अलग थी (डेबियन नहीं, बल्कि फ्रीबीएसडी), और गेंडा ऑटोस्टार्ट वाला मुद्दा खुला रहा। लालित्य के समाधान जो मुझे इंटरनेट पर मिले, उन्होंने या तो ढोंग नहीं किया: एक वेब एप्लिकेशन पर नौकरी करने के लिए - खराब शिष्टाचार। FreeBSD में, इस समस्या को पहली नज़र में "मेटा-सर्विसेज" बनाकर हल किया जाता है जो आपको एक से अधिक उदाहरण (उदाहरण के लिए, FreeBSD जेल) चलाने की अनुमति देता है। हालांकि, जैसा कि अक्सर होता है, बारीकियां होती हैं ...
rc.d
चूंकि सभी rc.d कॉन्फ़िगरेशन शेल स्क्रिप्ट हैं, आप
/etc/rc.conf
फ़ाइल और उसके साथी
/etc/rc.conf.local
से आगे जा सकते हैं, लेकिन
/etc/rc.conf.d
और
/usr/local/etc/rc.conf.d
में टुकड़े रखें
/usr/local/etc/rc.conf.d
केवल सिफारिश यह है कि फ़ाइलों को उसी तरह नामित किया जाना चाहिए जैसे कि सेवाओं का उपयोग करना। यह आपको कॉन्फ़िगरेशन फ़ाइलों को अपठनीय राक्षसों में सैकड़ों विषम रेखाओं से बदलने से बचने की अनुमति देता है जिन्हें आप बिना grep के समझ नहीं सकते हैं। समस्या अलग है: यदि सेवा के कई उदाहरण हैं, तो उनकी सभी सेटिंग्स औपचारिक रूप से एक ही फ़ाइल में होनी चाहिए (जिसका नाम, मुझे याद है, सेवा के नाम के साथ मेल खाता है)। इस समस्या को हल करने के लिए, आपको यह समझने की आवश्यकता है कि लॉन्चिंग सेवाओं के लिए स्क्रिप्ट कैसे काम करती है।
आमतौर पर, इस प्रक्रिया को लगभग इस प्रकार वर्णित किया जाता है: "जब सिस्टम शुरू होता है, तो स्क्रिप्ट
/etc/rc
निष्पादित होता है। यह
/etc/rc.conf
फ़ाइल (साथ ही
/etc/rc.conf.local
, यदि कोई हो) से सेटिंग्स पढ़ता है ..." और नहीं! इसके बजाय,
इसमें /etc/rc.subr
फ़ाइल शामिल है, जो कुछ सहायक कार्यों को परिभाषित करती है और
इसमें सिस्टम सेटिंग्स फ़ाइलें भी
शामिल हैं :
... if ${_rc_conf_loaded:-false}; then : else if [ -r /etc/defaults/rc.conf ]; then debug "Sourcing /etc/defaults/rc.conf" . /etc/defaults/rc.conf source_rc_confs elif [ -r /etc/rc.conf ]; then debug "Sourcing /etc/rc.conf (/etc/defaults/rc.conf doesn't exist)." . /etc/rc.conf fi _rc_conf_loaded=true fi if [ -f /etc/rc.conf.d/"$_name" ]; then debug "Sourcing /etc/rc.conf.d/${_name}" . /etc/rc.conf.d/"$_name" fi ...
बदले में,
/etc/defaults/rc.conf
फ़ाइल में निम्न कोड है:
... rc_conf_files="/etc/rc.conf /etc/rc.conf.local" ...
सभी सेटिंग्स को लोड करने के बाद, सिस्टम सेवाओं की एक सूची संकलित की जाती है, और प्रत्येक सेवा के लिए एक स्टार्टअप स्क्रिप्ट को कॉल किया जाता है - चाहे वह सक्षम हो या न हो। इसलिए,
उपयोगकर्ता सेवा फ़ाइलों को /etc/rc.d
निर्देशिका में रखने के लिए दृढ़ता से हतोत्साहित किया जाता है - इससे सिस्टम बूट समय बढ़ेगा। उपयोगकर्ता सेवाओं के लिए, एक निर्देशिका
/usr/local/etc/rc.d
- इसमें स्थित लिपियों को अंतिम कहा जाता है, जब मुख्य प्रणाली पहले से ही कॉन्फ़िगर है और काम करने के लिए तैयार है। लेकिन असली काला जादू आगे शुरू होता है: इनमें से प्रत्येक स्क्रिप्ट में फिर से
/etc/rc.subr
स्क्रिप्ट शामिल होती है, जिससे संबंधित चर को लोड किया जाता है। और यह और भी अधिक मॉड्यूलर विन्यास फाइल बनाना संभव बनाता है: बस मुख्य फ़ाइल में
/etc/rc.conf.d
निर्देशिका को निम्न की तरह एक कोड निर्देशिका में शामिल करें (तुरंत एक उदाहरण के रूप में गेंडा का उपयोग करके):
unicorn_enable="YES" unicorn_profiles="" for p in $(grep -rlE '^unicorn_[0-9a-zA-Z]+_enabled="[Yy][Ee][Ss]"$' /usr/local/etc/unicorn.d); do bn=$(basename $p) if [ -n "$unicorn_profiles" ]; then unicorn_profiles="$unicorn_profiles $bn" else unicorn_profiles="$bn" fi . $p done
एक तंगावाला
सबसे पहले, चलो
sudo
डालते हैं - यह "स्कल्पिंग" की तुलना में अधिक सुविधाजनक है, जो सू के माध्यम से चलने के लिए एक कमांड है, शेल इंजेक्शन के लिए पूछ रहा है।
cd /usr/ports/security/sudo && make install clean
हम पोर्टमास्टर नामक एक उपयोगिता भी डालेंगे - इससे आगे की प्रक्रिया आसान होगी:
cd /usr/ports/ports-mgmt/portmaster && make install clean
हम इसकी मदद से बाकी सॉफ्टवेयर स्थापित करेंगे:
LN='ln -f' portmaster devel/bison textproc/libxml2 textproc/libxslt textproc/diffutils devel/gmake security/openssl devel/automake devel/git devel/subversion shells/bash
आलसी के लिए - डिफ़ॉल्ट वातावरण सेट करना:
portmaster lang/ruby19 sysutils/rubygem-bundler www/rubygem-unicorn
आगे के चरणों का विवरण मूल लेख में पाया जा सकता है, और हम अगले भाग पर चलते हैं - इस सभी सामान को सेवा के रूप में स्थापित करना।
सेवा के कई उदाहरणों को प्रबंधित करने में सक्षम होने के लिए, निम्न कोड को स्टार्टअप स्क्रिप्ट में शामिल किया जाना चाहिए:
is_unicorn_profile() { local profile for profile in $unicorn_profiles; do if [ "$profile" = "$1" ]; then return 0 fi done return 1 } if [ -n "${unicorn_profiles}" ]; then if [ -n "$2" ]; then profile="$2" if ! is_unicorn_profile $profile; then echo "$0: no such profile defined in unicorn_profiles." exit 1 fi eval unicorn_socket=\${unicorn_${profile}_socket:-"/tmp/${name}-${profile}.sock"} eval unicorn_config=\${unicorn_${profile}_config} eval unicorn_dir=\${unicorn_${profile}_dir} eval unicorn_flags=\${unicorn_${profile}_flags:-"${unicorn_flags}"} eval unicorn_environment=\${unicorn_${profile}_environment:-"${unicorn_environment}"} eval unicorn_rails=\${unicorn_${profile}_rails:-"${unicorn_rails}"} eval unicorn_user=\${unicorn_${profile}_user:-"${unicorn_user}"} eval unicorn_procname=\${unicorn_${profile}_procname:-"${unicorn_procname}"} eval unicorn_bundler=\${unicorn_${profile}_bundler:-"${unicorn_bundler}"} eval unicorn_rvm=\${unicorn_${profile}_rvm:-"${unicorn_rvm}"} eval unicorn_ruby=\${unicorn_${profile}_ruby:-"${unicorn_ruby}"} if checkyesno unicorn_rvm; then unicorn_procname="~${unicorn_user}/.rvm/rubies/ruby-${unicorn_ruby}/bin/ruby" fi elif [ -n "$1" ]; then for profile in ${unicorn_profiles}; do echo "Processing ${name} profile: ${profile}" $0 $1 ${profile} done exit 0 fi fi
आरवीएम का उपयोग करने से समस्या उत्पन्न होती है: विभिन्न अनुप्रयोगों के लिए पर्यावरण को ठीक करना आवश्यक है। बेशक, आप प्रत्येक उदाहरण को शुरू करने के बाद, पर्यावरण को फिर से संगठित कर सकते हैं, लेकिन सहायक स्क्रिप्ट का उपयोग करना आसान है:
if checkyesno unicorn_rvm; then if [ -d "~${unicorn_user}/.rvm/${unicorn_ruby}" ]; then /usr/local/bin/sudo -u $unicorn_user /usr/bin/env SHELL=/usr/local/bin/bash CDPATH=. /usr/local/bin/unicorn-wrapper ${unicorn_ruby} $(basename ${command}) ${command_args} rc=$? else echo "Ruby version ${unicorn_ruby} not found by RVM for user ${unicorn_user}" rc=1 fi else /usr/local/bin/sudo -u $unicorn_user ${command} ${command_args} rc=$? fi
परीक्षण के दौरान, यह पता चला है कि यदि ZSH का उपयोग किया जाता है, तो
ZSH_VERSION=""
को पुन: परिभाषित चर की सूची में जोड़ना आवश्यक है। फ़ाइल
/usr/local/bin/unicorn-wrapper
एक सरल आवरण है जो रूबी के आवश्यक संस्करण को स्थापित करता है और किसी दिए गए आदेश को तर्कों के साथ निष्पादित करता है। स्टार्टअप स्क्रिप्ट का पूरा संस्करण
पास में लिया जा सकता
है । का उपयोग करना बहुत सरल है:
service unicorn <action> [<app>]
विन्यास उदाहरण:
unicorn_redmine_enabled="YES" unicorn_redmine_dir="/var/www/sites/mycoolsite.tld/redmine" unicorn_redmine_rails="NO"
एक अच्छे तरीके से, पोर्ट अनुरोध जारी करना आवश्यक होगा, लेकिन अभी तक हाथ नहीं पहुंचे हैं।
पुनश्च केवल एक प्रश्न खुला रहा: मैं इस सामग्री को उसी कैपिस्ट्रानो के साथ कैसे एकीकृत कर सकता हूं ताकि अपडेट के दौरान सेटिंग्स उड़ न जाएं?