Linux VPS पर systemd service कैसे बनाएं और चलाएं
Linux VPS पर अपने प्रोग्राम को systemd service के रूप में चलाने का तरीका जानें। यह गाइड आपको unit file लिखने, ऑटो-रीस्टार्ट सेट करने और लॉग्स को मैनेज करने की प्रक्रिया सिखाएगी।
systemd service क्या है और इसकी आवश्यकता क्यों है
systemd service एक छोटी टेक्स्ट फाइल होती है जो सर्वर को बताती है कि किसी प्रोग्राम को कैसे चलाना है: इसे बूट पर शुरू करना, क्रैश होने पर रीस्टार्ट करना और इसके आउटपुट को सिस्टम लॉग में भेजना। इसका पूरा काम यही है। SSH सेशन में आपके द्वारा मैन्युअल रूप से शुरू किया गया प्रोग्राम आपके लॉग आउट करते ही या सर्वर के रीबूट होते ही बंद हो जाता है। systemd service में रैप किया गया प्रोग्राम चलता रहता है, क्योंकि इसे आपके शेल के बजाय स्वयं सर्वर नियंत्रित करता है।
systemd, Ubuntu, Debian, Fedora और अधिकांश आधुनिक Linux सर्वरों पर init सिस्टम है। यह शुरू होने वाली पहली प्रक्रिया है और यही बाकी सभी चीजों की निगरानी करती है। यह हमेशा से ऐसा नहीं था, और systemd ने पहले के init scripts की जगह कैसे ली यह जानना तब उपयोगी है जब आप समझ जाएं कि unit file क्या करती है। जब आप एक सर्विस फाइल लिखते हैं, तो आप अपने प्रोग्राम को उस सुपरवाइजर को सौंप देते हैं। यह गाइड सबसे छोटी कार्यशील यूनिट, हर यूनिट के तीन सेक्शन, इसे चालू करने और इसके लॉग पढ़ने का तरीका, इसे टाइमर के साथ शेड्यूल पर चलाने का तरीका, और इसे कम से कम विशेषाधिकारों के साथ चलाने के लिए सुरक्षित करने का तरीका बताती है।
सबसे छोटी कार्यशील service
एक service file /etc/systemd/system/ में रहती है, .service पर समाप्त होती है, और इसमें केवल कुछ पंक्तियों की आवश्यकता होती है। /usr/local/bin/myapp पर स्थित प्रोग्राम के लिए एक file बनाएँ:
sudo nano /etc/systemd/system/myapp.service[Unit]
Description=My application
[Service]
ExecStart=/usr/local/bin/myapp
[Install]
WantedBy=multi-user.targetयह एक पूर्ण, कार्यशील unit है। ExecStart वह command है जिसे चलाना है। WantedBy=multi-user.target का अर्थ है कि सर्वर के सामान्य multi-user operation तक पहुँचने पर इसे start करें, जो इसे boot के समय चालू करता है। बाकी सब कुछ केवल सुधार है।
तीन सेक्शन और उनका उद्देश्य
प्रत्येक unit file को square brackets में दिए गए सेक्शन में विभाजित किया जाता है। एक service तीन सेक्शन का उपयोग करती है।
[Unit] सर्विस और उसके संबंधों का वर्णन करता है। वे दो लाइनें जिनका आप सबसे अधिक उपयोग करेंगे:
[Unit]
Description=My application
After=network-online.target
Wants=network-online.targetDescription वह human label है जिसे आप systemctl status में देखते हैं। After=network-online.target systemd को निर्देश देता है कि वह आपके प्रोग्राम को तब तक start न करे जब तक network up न हो जाए, जो किसी भी ऐसी चीज़ के लिए महत्वपूर्ण है जो port bind करती है या outbound connection बनाती है।
[Service] यह निर्धारित करता है कि प्रोग्राम कैसे चलता है। अधिकांश सेटिंग्स यहीं होती हैं:
[Service]
ExecStart=/usr/local/bin/myapp --config /etc/myapp/config.toml
WorkingDirectory=/opt/myapp
User=myapp
Restart=on-failure
RestartSec=5
Environment=LOG_LEVEL=infoUser=myapp प्रोग्राम को root के बजाय एक unprivileged account के रूप में चलाता है, जो सुरक्षा के लिए सबसे महत्वपूर्ण लाइन है। यहाँ कोई Type= लाइन नहीं है, इसलिए systemd डिफ़ॉल्ट रूप से simple का उपयोग करता है और यह मान लेता है कि ExecStart प्रोसेस foreground में रहती है; जो प्रोग्राम background में fork होता है, उसे start होने के सही Type= की आवश्यकता होती है, अन्यथा unit active दिखाई देगी जबकि वास्तविक daemon पहले ही बंद हो चुका होगा। Restart=on-failure और RestartSec=5 का अपना सेक्शन नीचे दिया गया है, क्योंकि यही वे कारण हैं जिनके लिए अधिकांश लोग service लिखते हैं।
[Install] यह बताता है कि service enable करने पर क्या होता है:
[Install]
WantedBy=multi-user.targetWantedBy=multi-user.target वह है जो service को boot प्रक्रिया से जोड़ता है जब आप systemctl enable चलाते हैं। [Install] सेक्शन के बिना, service को हाथ से start तो किया जा सकता है, लेकिन वह reboot के बाद अपने आप start नहीं होगी।
इसे चालू करें और मॉनिटर करें
किसी भी unit file को लिखने या संपादित करने के बाद, systemd को reload करें ताकि वह बदलावों को पढ़ सके, फिर service को enable और start करें:
sudo systemctl daemon-reload
sudo systemctl enable --now myapp.servicedaemon-reload वह चरण है जिसे लोग अक्सर भूल जाते हैं: systemd unit files को cache करता है, इसलिए reload किए बिना कोई भी संपादन प्रभावी नहीं होता है। enable --now service को boot के लिए enable भी करता है और उसे तुरंत start भी कर देता है। इसकी जाँच करें:
sudo systemctl status myapp.service* myapp.service - My application
Loaded: loaded (/etc/systemd/system/myapp.service; enabled)
Active: active (running) since Wed 2026-07-15 22:40:11 UTC; 3s ago
Main PID: 4123 (myapp)Active: active (running) और enabled वही हैं जो आपको चाहिए। प्रोग्राम का output पढ़ने के लिए, journal से केवल इस unit के लिए अनुरोध करें:
sudo journalctl -u myapp.service -f-f नई लाइनों को वैसे ही follow करता है जैसे वे आती हैं, बिल्कुल tail -f की तरह। आपका प्रोग्राम standard output या standard error पर जो कुछ भी लिखता है, वह यहाँ दिखाई देता है, इसके लिए आपको कोई logging setup करने की आवश्यकता नहीं है।
विफलता पर पुनरारंभ (Restart), आप यहाँ क्यों हैं
Service का मुख्य लाभ यह है कि जब आपका प्रोग्राम बंद हो जाता है, तो systemd उसे पुनरारंभ (restart) कर देता है। इसे दो पंक्तियाँ करती हैं:
[Service]
Restart=on-failure
RestartSec=5Restart=on-failure प्रोग्राम को तब पुनरारंभ करता है जब वह non-zero कोड के साथ exit करता है या SIGKILL या SIGSEGV जैसे क्रैश सिग्नल के कारण बंद हो जाता है। एक clean exit, या SIGTERM, SIGINT, SIGHUP, या SIGPIPE द्वारा रोका जाना, इसे ट्रिगर नहीं करता है। RestartSec=5 प्रयासों के बीच पाँच सेकंड प्रतीक्षा करता है, ताकि तुरंत क्रैश होने वाला प्रोग्राम एक tight loop में न फँसे। प्रक्रिया (process) को kill करके और systemd को उसे वापस लाते हुए देखकर इसकी पुष्टि करें। SIGKILL का उपयोग करें: डिफ़ॉल्ट SIGTERM एक clean stop माना जाता है, इसलिए on-failure सेवा को पुनरारंभ नहीं करेगा:
sudo systemctl kill -s SIGKILL myapp.service
sudo systemctl status myapp.serviceपाँच सेकंड के भीतर status एक नया Main PID दिखाता है और active (running) फिर से सक्रिय हो जाता है। यह पूरी सुविधा है, और यही कारण है कि एक service को tmux या screen में प्रोग्राम को चलते हुए छोड़ने से बेहतर माना जाता है।
इसे एक unprivileged user के रूप में चलाएं और harden करें
यदि कोई प्रोग्राम कभी exploit हो जाए, तो root के रूप में चलने वाली service आपके सर्वर के साथ कुछ भी कर सकती है। इसे इसके अपने user के रूप में चलाएं और systemd को कुछ directives दें जो इसे सुरक्षित घेरे में रखें। सबसे पहले बिना login और बिना home directory वाला एक system account बनाएं:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin myappफिर User=myapp सेट करें और [Service] में hardening lines जोड़ें:
[Service]
User=myapp
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=trueप्रत्येक line ऐसी चीज को हटाती है जिसकी प्रोग्राम को आवश्यकता नहीं है। NoNewPrivileges=true process को कभी भी नए privileges प्राप्त करने से रोकता है, यहाँ तक कि setuid binary के माध्यम से भी। PrivateTmp=true इसे एक private /tmp देता है जिसे कोई अन्य process नहीं देख सकता। ProtectSystem=strict पूरे filesystem को read-only बना देता है, सिवाय उन कुछ paths के जिन्हें आप ReadWritePaths= के साथ नाम देते हैं। ProtectHome=true इसे /home से पूरी तरह छिपा देता है। यह least-privilege की वही सोच है जो किसी service को firewall के पीछे रखने की होती है: इसे केवल वही दें जिसकी इसे आवश्यकता है। यदि आपने VPS पर IPv6 firewall gap को बंद करने पर गाइड पढ़ी है, तो यह उसी विचार का on-host हिस्सा है। इंटरनेट का सामना करने वाली service के लिए, इस hardening को SSH के सामने Fail2ban और default-deny firewall के साथ जोड़ें।
इन सबको हाथ से टाइप करने और किसी directive को गलत याद रखने के बजाय, एक पूर्ण, hardened unit generate करें और उसे copy कर लें:
Timers: आधुनिक cron
systemd timer एक schedule पर service चलाता है, और यह cron job का आधुनिक विकल्प है। एक timer दो फाइलों से बनता है: एक .service जो काम करती है, और एक .timer जो समय निर्धारित करती है। मान लीजिए आप हर दिन सुबह 3 बजे backup चाहते हैं। Service कार्य को एक बार करती है और बंद हो जाती है:
# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.shType=oneshot systemd को बताता है कि program चलता है, समाप्त होता है, और पूरा हो जाता है, बजाय इसके कि वह resident रहे। Timer इसे schedule करता है:
# /etc/systemd/system/backup.timer
[Unit]
Description=Run the nightly backup
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.targetOnCalendar=*-*-* 03:00:00 का अर्थ है हर दिन सुबह 3 बजे। किसी भी calendar expression को systemd-analyze calendar "*-*-* 03:00:00" के साथ test करें, जो यह पुष्टि करता है कि यह parse हो गया है और अगली बार चलने का समय print करता है। Persistent=true यदि सर्वर सुबह 3 बजे बंद था, तो सर्वर के वापस आने पर छूटे हुए job को तुरंत चलाता है, जो cron नहीं कर सकता। ध्यान दें कि timer को timers.target के माध्यम से enable किया जाता है, न कि multi-user.target के माध्यम से। Service को नहीं, बल्कि timer को enable करें:
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timerslist-timers हर timer को उसके अगले और पिछले run के साथ दिखाता है, ताकि आप एक नज़र में देख सकें कि आपका job अगली बार कब चलेगा। जब आप timer mode चालू करते हैं, तो ऊपर दिया गया generator आपके लिए युग्मित .service और .timer बनाता है। Cron line की तुलना में, एक timer आपको journal में वास्तविक logs, किसी भी service के समान hardening directives, और वह missed-run catch-up देता है जो Persistent=true प्रदान करता है। साधारण job के लिए Cron अभी भी ठीक है; जब job महत्वपूर्ण हो, तो timer बेहतर उपकरण है।
FAQ
systemd service और cron job में क्या अंतर है?
एक service लंबे समय तक चलने वाले प्रोग्राम को सक्रिय रखती है: यह बूट पर शुरू होती है, विफलता पर पुनः आरंभ होती है, और journal में लॉग लिखती है। एक cron job एक निर्धारित समय पर एक छोटा कमांड चलाती है और फिर समाप्त हो जाती है। जब आपको शेड्यूलिंग के साथ-साथ journal लॉग्स, सुरक्षा और छूटे हुए कार्यों को पूरा करने की आवश्यकता हो, तो systemd timer का उपयोग करें। यह एक .timer शेड्यूल को एक oneshot service के साथ जोड़ता है और अधिकांश सर्वर कार्यों के लिए cron की जगह ले लेता है।
मुझे अपनी systemd service फाइल कहाँ रखनी चाहिए?
अपनी खुद की units को /etc/systemd/system/ में रखें, जिसका नाम .service पर समाप्त होना चाहिए। वह डायरेक्टरी प्रशासक द्वारा जोड़ी गई units के लिए है, और यह /lib/systemd/system/ में पैकेजों द्वारा प्रदान की गई units से अधिक प्राथमिकता लेती है। वहाँ फाइल बनाने या संपादित करने के बाद, sudo systemctl daemon-reload चलाएँ ताकि systemd बदलावों को लागू कर सके।
यदि service क्रैश हो जाए तो मैं उसे पुनः आरंभ कैसे करूँ?
[Service] सेक्शन में Restart=on-failure और RestartSec=5 जोड़ें, फिर sudo systemctl daemon-reload चलाएँ और service को पुनः आरंभ करें। जब प्रोग्राम नॉन-जीरो कोड के साथ समाप्त होता है या क्रैश सिग्नल के कारण बंद हो जाता है, तो systemd उसे पुनः लॉन्च करता है और प्रयासों के बीच पाँच सेकंड प्रतीक्षा करता है। इसे sudo systemctl kill -s SIGKILL myapp.service के साथ टेस्ट करें; SIGTERM, जो कि डिफ़ॉल्ट सिग्नल है, एक साफ स्टॉप माना जाता है और यह on-failure को ट्रिगर नहीं करता है। देखें कि systemctl status कुछ ही सेकंड में एक नया PID दिखाता है।
मैं systemd service को non-root user के रूप में कैसे चलाऊँ?
sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp के साथ एक system account बनाएँ, फिर [Service] सेक्शन में User=myapp जोड़ें। NoNewPrivileges=true, PrivateTmp=true, और ProtectSystem=strict जोड़ें ताकि प्रक्रिया को केवल उतनी ही एक्सेस मिले जितनी उसे आवश्यकता है। एक unprivileged user के रूप में चलाना service की सुरक्षा के लिए किया जाने वाला सबसे महत्वपूर्ण बदलाव है।
मेरी service शुरू होने में विफल क्यों रही?
सारांश के लिए systemctl status myapp.service और पूर्ण आउटपुट के लिए journalctl -u myapp.service चलाएँ। सबसे सामान्य कारण ExecStart में गलत पाथ, किसी WorkingDirectory का गायब होना, परमिशन एरर क्योंकि User= किसी फाइल को पढ़ नहीं सकता, या संपादन के बाद भूला हुआ sudo systemctl daemon-reload है। जर्नल प्रोग्राम का अपना एरर मैसेज दिखाता है, जो आमतौर पर समस्या का सीधा नाम बताता है।