systemd service Type: simple, forking, notify का सही चुनाव
क्या आपकी systemd service active है पर daemon बंद हो चुका है? simple, forking, notify और oneshot के बीच का अंतर समझें और अपनी unit के लिए सही main PID ट्रैक करना सीखें।
systemd किसी unit को active क्यों दिखाता है जबकि process समाप्त हो चुकी है
एक systemd service unit तब तक active रहती है जब तक वह process जीवित है जिसे systemd मुख्य process मानता है, और [Service] section में मौजूद Type= यह तय करता है कि वह process कौन सी है। यदि आप गलत value चुनते हैं, तो systemd किसी shell wrapper या अल्पकालिक parent process की निगरानी करने लगता है, जबकि वह daemon जिसकी आपको परवाह है, उसी unit के भीतर समाप्त हो जाता है। unit आपको उस process के बारे में सही जानकारी दे रही है जिसकी निगरानी करने के लिए उसे कहा गया था।
restart policy बदलने से यहाँ कोई मदद नहीं मिलेगी। Restart= तब काम करता है जब मुख्य process exit होती है, इसलिए Restart=always कभी trigger नहीं होता जब तक main PID (process identifier) किसी ऐसी चीज़ से संबंधित है जो अभी भी चल रही है। पहले Type= को ठीक करें। मुख्य process के वास्तव में exit होने के बाद systemd क्या करता है, यह एक अलग निर्णय है, जिसे Restart= और RestartSec= के लिए गाइड में कवर किया गया है।
Type= वास्तव में क्या निर्धारित करता है
प्रत्येक Type= मान एक साथ दो सवालों के जवाब देता है। systemd कब इस unit को 'started' मान सकता है, और मुख्य process कौन सी है।
पहला जवाब ordering को नियंत्रित करता है। जो unit After= में आपकी unit का नाम लेती है, वह तब तक प्रतीक्षा करती है जब तक systemd आपकी unit को 'started' घोषित न कर दे। यदि कोई Type= बहुत जल्दी "started" रिपोर्ट कर देता है, तो dependent units आपकी service के तैयार होने से पहले ही चलने लगती हैं।
दूसरा जवाब supervision को नियंत्रित करता है। systemd एक unit द्वारा spawn की गई हर process को एक cgroup (control group) में रखता है। यह kernel का एक feature है जो processes को समूहबद्ध करता है ताकि उन्हें एक साथ सीमित किया जा सके या बंद किया जा सके। cgroup ही वह तरीका है जिससे systemctl stop cleanup करता है: KillMode= का default मान control-group होता है, इसलिए unit को stop करने पर उसके अंदर की हर process को signal भेजा जाता है। main PID का दायरा इससे छोटा होता है। यह वह एकमात्र process है जिसके exit होने पर unit समाप्त मानी जाती है, और जिसका exit status ही unit का परिणाम बनता है। cgroup को main PID की तरह पढ़ना ही भ्रम का मुख्य कारण है।
Type=simple रिपोर्ट तब शुरू होती है जब बाइनरी चलती है
जब ExecStart= सेट हो और Type= या BusName= में से कोई भी मौजूद न हो, तो Type=simple डिफ़ॉल्ट होता है। systemd प्रक्रिया बनाता है, यूनिट को तुरंत शुरू हुआ मानता है, और उस प्रक्रिया को मुख्य PID के रूप में देखता है। फॉलो-अप यूनिट्स तुरंत शुरू हो जाती हैं, इससे पहले कि सर्विस बाइनरी निष्पादित (execute) भी हुई हो।
यह अंतिम विवरण एक सामान्य आश्चर्य की व्याख्या करता है। ExecStart= पथ में एक टाइपो (typo) अभी भी एक स्टार्ट जॉब बनाता है जो सफल हो जाता है, और विफलता एक क्षण बाद आती है जब निष्पादन (execution) विफल हो जाता है। systemd उस मामले को एग्जिट कोड 203 के साथ रिकॉर्ड करता है, जिसे उसकी अपनी तालिका EXEC नाम देती है और इसे सर्विस बाइनरी को निष्पादित करने में विफलता के रूप में परिभाषित करती है। इसलिए, बिना किसी त्रुटि के systemctl start का वापस आना यह साबित नहीं करता है कि आपकी बाइनरी मौजूद है।
ऐसे प्रोग्राम के लिए simple का उपयोग करें जो फोरग्राउंड में रहता है और खुद को कभी बैकग्राउंड में नहीं ले जाता है। यह अधिकांश आधुनिक डेमन्स (daemons) और आपके द्वारा लिखे गए लगभग किसी भी प्रोग्राम को कवर करता है।
Type=exec यह सुनिश्चित करता है कि प्रोग्राम वास्तव में शुरू हो गया है
Type=exec, simple का ही एक उन्नत रूप है जिसमें एक अतिरिक्त चरण शामिल है। systemd यूनिट को तभी शुरू हुआ मानता है जब fork और binary का निष्पादन (execution) दोनों सफल हो जाते हैं। यदि binary मौजूद न हो या User= को resolve न किया जा सके, तो अब start job विफल हो जाएगी। इसके बजाय कि यह पहले सफलता की रिपोर्ट दे और बाद में चुपचाप विफल हो जाए।
Type=exec को systemd 240 में पेश किया गया था, इसलिए वर्तमान की सभी सर्वर distributions में यह उपलब्ध है। अगस्त 2026 तक, Ubuntu 24.04 में systemd 255 और Debian 13 में systemd 257 शामिल है। अपने सिस्टम का वर्ज़न systemctl --version के साथ जाँचें।
इसका नुकसान यह है कि शुरू होने के समय एक अतिरिक्त सिंक्रोनाइज़ेशन चरण लगता है। इसका लाभ यह है कि systemctl start से एक सटीक exit status प्राप्त होता है। foreground प्रोग्राम के लिए, simple के बजाय exec का उपयोग करना बेहतर है।
Type=forking, और मुख्य PID कैसे खो जाता है
Type=forking systemd को बताता है कि ExecStart= में दिया गया process एक child process बनाएगा और फिर जानबूझकर exit हो जाएगा। systemd उस पहले process के exit होने का इंतज़ार करता है और उसके बाद ही unit को started मानता है। पीछे रह जाने वाला child process ही daemon होता है। यह आदत SysV युग से चली आ रही है, जब init script के वापस आने के बाद daemon की निगरानी करने वाला कोई नहीं होता था और PID file ही एकमात्र रिकॉर्ड होती थी कि क्या चल रहा है। यह एक ऐसी सीमा है जो systemd ने init scripts की जगह क्यों ली के मुख्य कारणों में से एक है।
कठिनाई पहचान की है। जिस process को systemd ने launch किया था, वह अब मौजूद नहीं है, इसलिए systemd को यह पता लगाना पड़ता है कि बचा हुआ कौन सा process मुख्य है। PIDFile= को उस file पर सेट करें जिसे daemon लिखता है, जो आमतौर पर /run के अंतर्गत एक path होता है, और systemd उससे PID पढ़ लेता है। systemd यह भी जाँचता है कि उस file में मौजूद PID उसी service से संबंधित किसी process का है या नहीं, ताकि किसी unrelated process का नाम बताने वाली पुरानी file पर भरोसा करने के बजाय उसे reject किया जा सके।
PIDFile= के बिना, GuessMainPID= लागू होता है, और यह डिफ़ॉल्ट रूप से yes पर होता है। यह अनुमान तभी विश्वसनीय होता है जब service एक ही process में स्थिर हो जाए। manual इस सीमा को स्पष्ट रूप से बताता है: यदि daemon एक से अधिक processes से बना है, तो अनुमान गलत हो सकता है, और failure detection काम करना बंद कर देता है। एक unit का मुख्य PID 0 भी हो सकता है, जिसका अर्थ है कि systemd के पास निगरानी के लिए कुछ भी नहीं है।
fork करने वाले अधिकांश daemons में एक switch भी होता है जो उन्हें foreground में रखता है। Type=exec के साथ उस switch का उपयोग करें और PIDFile= line को हटा दें। कम moving parts का मतलब है PID खोने की कम संभावना।
Type=oneshot ऐसे कार्यों के लिए जो पूर्ण हो जाते हैं
Type=oneshot यह अपेक्षा करता है कि प्रक्रिया चले और समाप्त हो जाए। systemd यूनिट को तभी started मानता है जब वह समाप्त हो जाती है, जो oneshot को किसी भी ऐसी चीज़ के लिए सही स्वरूप बनाता है जिसका अन्य यूनिट्स को इंतज़ार करना चाहिए। जब कोई यूनिट न तो Type= और न ही ExecStart= निर्दिष्ट करती है, तो यह निहित डिफ़ॉल्ट भी होता है।
दो व्यवहार विशेष रूप से oneshot के लिए हैं। यह एकमात्र प्रकार है जो एक से अधिक ExecStart= लाइनों को स्वीकार करता है, और वे लाइनें क्रम में चलती हैं। इसका start timeout भी डिफ़ॉल्ट रूप से अक्षम होता है, इसलिए यदि आप स्वयं TimeoutStartSec= सेट नहीं करते हैं, तो एक oneshot जो हैंग हो जाता है, वह हमेशा के लिए इंतज़ार करेगा।
प्रक्रिया के समाप्त होने के बाद, यूनिट inactive स्थिति में लौट आती है। RemainAfterExit=yes इसे बिना किसी चल रही प्रक्रिया के active बनाए रखता है। यह इस पृष्ठ के शीर्ष पर बताए गए लक्षण का जानबूझकर किया गया संस्करण है, और यह तब सही होता है जब यूनिट का कार्य किसी चीज़ को चालू रखने के बजाय स्थिति (state) को पीछे छोड़ना हो: जैसे firewall ruleset लोड करना, या container stack को चालू करना। यह reboot के बाद वापस आने वाले Docker Compose stack के पीछे का पैटर्न है, जहाँ यूनिट compose कमांड चलाती है, समाप्त हो जाती है, और active बनी रहती है क्योंकि इसके द्वारा शुरू किए गए containers इसके बाद भी चलते रहते हैं। एक oneshot यूनिट वह भी है जिसे schedule ट्रिगर करता है, जो cron के बजाय systemd timer पर जॉब चलाने का दूसरा भाग है।
Type=notify सेवा को यह बताने की अनुमति देता है कि वह कब तैयार है
Type=notify निर्णय लेने की जिम्मेदारी सेवा पर डाल देता है। systemd तब तक start job को खुला रखता है जब तक कि process एक Unix socket पर READY=1 नहीं भेज देती, जिसका path उसे NOTIFY_SOCKET environment variable में प्राप्त होता है। इसका C interface sd_notify(3) है, और कई servers पहले से ही इसका समर्थन करते हैं।
यह "क्या यह शुरू हो गया है" प्रश्न का सटीक उत्तर है। simple और exec सेवा द्वारा अपना configuration पढ़ने या listening socket खोलने से पहले ही 'started' की रिपोर्ट दे देते हैं, जिससे कोई dependent unit बहुत जल्दी शुरू हो सकती है और अपना पहला connection विफल कर सकती है। notify उस क्षण 'started' की रिपोर्ट देता है जब सेवा स्वयं यह कहती है कि वह तैयार है।
systemd केवल मुख्य process से ही वह संदेश स्वीकार करता है, जिसका अर्थ NotifyAccess=main है, और Type=notify इसे सूचित करता है। यदि संदेश किसी child या helper process से आता है, तो NotifyAccess=all सेट करें। एक shell script systemd-notify --ready को कॉल कर सकती है, लेकिन वह एक अलग अल्पकालिक process के रूप में चलती है, इसलिए उसे NotifyAccess=all की आवश्यकता होती है और हो सकता है कि systemd उस संदेश को न पहचान पाए जिसका प्रेषक पहले ही समाप्त हो चुका है। जो सेवा स्वयं protocol का पालन करती है, वह अधिक विश्वसनीय होती है।
दो संबंधित settings जानने योग्य हैं। Type=notify-reload, जो systemd 253 से उपलब्ध है, उसी handshake को reloads तक विस्तारित करता है, इसलिए systemctl reload तब return होता है जब सेवा यह रिपोर्ट करती है कि reload पूरा हो गया है, न कि तब जब signal भेजा गया था। WatchdogSec= एक notifying सेवा को एक निश्चित अंतराल पर keep-alive संदेश भेजने के लिए कहता है, और systemd समय सीमा चूकने को विफलता मानता है।
Type=dbus और Type=idle
Type=dbus तब तक प्रतीक्षा करता है जब तक service D-Bus पर कोई नाम register नहीं कर लेती। D-Bus वह message bus है जिसका उपयोग system और desktop services एक-दूसरे से संवाद करने के लिए करती हैं। इसके लिए BusName= की आवश्यकता होती है, और जैसे ही BusName= सेट किया जाता है, यह default बन जाता है। इसका उपयोग केवल उसी service के लिए करें जो वास्तव में bus name register करती है।
Type=idle, simple की तरह कार्य करता है, लेकिन यह program को चलाने में तब तक देरी करता है जब तक कि queued jobs dispatch न हो जाएं। इसमें पांच सेकंड की समय सीमा होती है। यह इसलिए मौजूद है ताकि boot के समय console output, status messages के साथ न मिल जाए। यह एक ordering tool नहीं है, और इसे सामान्य service पर उपयोग नहीं किया जाना चाहिए।
Wrapper script के कारण systemd का गलत PID पर अटक जाना
यहाँ वह संरचना दी गई है जो मूल समस्या उत्पन्न करती है।
[Service]
Type=simple
ExecStart=/opt/app/run.sh#!/bin/bash
export APP_ENV=production
/opt/app/bin/server --config /etc/app.yaml &
/opt/app/bin/exporter --port 9101systemd शेल को मुख्य PID के रूप में रिकॉर्ड करता है। जब तक exporter फोरग्राउंड में चलता है, शेल जीवित रहता है। यदि server समाप्त हो जाता है, तो शेल को इसका पता नहीं चलता है, इसलिए मुख्य PID अभी भी जीवित है, यूनिट अभी भी active है, और Restart= के पास कार्रवाई करने के लिए कुछ नहीं है। दोनों प्रक्रियाएं पूरे समय यूनिट के cgroup में रहती हैं, इसलिए systemctl stop अभी भी सही ढंग से सफाई करता है। पर्यवेक्षण (supervision) टूटा है, सफाई नहीं।
इसका समाधान इस बात पर निर्भर करता है कि यूनिट में वास्तव में कितनी लंबी चलने वाली प्रक्रियाएं हैं।
यदि केवल एक प्रक्रिया है, तो शेल को उससे बदल दें।
#!/bin/bash
export APP_ENV=production
exec /opt/app/bin/server --config /etc/app.yamlexec शेल को नामित प्रोग्राम से बदल देता है और वही PID रखता है, इसलिए systemd द्वारा रिकॉर्ड किया गया PID अब डेमन (daemon) का है। इससे भी बेहतर, रैपर को हटा दें। Environment= और EnvironmentFile= वेरिएबल्स को ले जाते हैं, और ExecStartPre= सेटअप चरण को संभालता है, ताकि systemd सीधे डेमन को लॉन्च कर सके और निर्माण के आधार पर ही उसका PID जान सके।
यदि दो प्रक्रियाएं हैं, तो कोई भी एक PID यूनिट का प्रतिनिधित्व नहीं करता है। उन्हें दो यूनिट्स में विभाजित करें और After= तथा Wants= के साथ उनका क्रम निर्धारित करें। प्रति प्रक्रिया एक यूनिट वह व्यवस्था है जिसे systemd अच्छी तरह से पर्यवेक्षित करता है, और यही एकमात्र तरीका है जिससे प्रत्येक प्रक्रिया को अपना स्वयं का रीस्टार्ट व्यवहार मिलता है।
ExitType=cgroup में क्या बदलाव आए
ExitType= को systemd 250 में जोड़ा गया था। डिफ़ॉल्ट मान main है: जब मुख्य process समाप्त हो जाती है, तो unit को बंद माना जाता है। ExitType=cgroup के साथ, unit को तब तक चलता हुआ माना जाता है जब तक कि उसके cgroup में कोई भी process जीवित है।
[Service]
Type=simple
ExitType=cgroup
ExecStart=/opt/app/launcherयह एक विशिष्ट समस्या का समाधान करता है। एक launcher जो वास्तविक कार्य शुरू करता है और फिर exit हो जाता है, वह ExitType=main के तहत systemd को यह सोचने पर मजबूर करेगा कि unit बंद हो गई है और वह बचे हुए processes को kill कर देगा। ExitType=cgroup के साथ unit पूरे group का अनुसरण करती है।
यह स्पष्ट रहें कि यह क्या हल नहीं करता है। ExitType=cgroup unit को तब तक सक्रिय रखता है जब तक कम से कम एक process जीवित है, इसलिए दो daemons वाली unit उनमें से एक के मरने के बाद भी सक्रिय रहती है। यह launcher वाली स्थिति को ठीक करता है। यह एक unit को कई स्वतंत्र processes के supervisor में नहीं बदलता है। ExitType= को Type=oneshot के साथ भी संयोजित नहीं किया जा सकता है।
cgroup वह स्थान है जहाँ resource accounting भी होती है, इसलिए MemoryMax= और CPUQuota= जैसी सीमाएँ unit द्वारा spawn की गई हर process पर लागू होती हैं, चाहे Type= मुख्य PID के बारे में कुछ भी कहे। इसका वह पहलू systemd के साथ service की memory और CPU को सीमित करना में दिया गया है।
systemd जिस process को वास्तव में monitor कर रहा है, उसे कैसे खोजें
जिस unit को आप debug कर रहे हैं, उस पर क्रमवार तरीके से काम करें। पहले यह पढ़ें कि systemd ने क्या load किया है, फिर देखें कि वह किसे track कर रहा है, और अंत में इसकी तुलना process table से करें।
systemctl cat app.service
systemctl show -p Type,ExitType,GuessMainPID,PIDFile,MainPID,RemainAfterExit app.servicesystemctl cat unit file को उन सभी drop-in files के साथ print करता है जो उस पर लागू होती हैं, ताकि आप वह पढ़ सकें जो systemd ने load किया है, न कि वह file जिसे आपने edit किया था। systemctl show प्रभावी values को print करता है, जिसमें वे defaults भी शामिल हैं जिन्हें आपने कभी नहीं लिखा था। आगे बढ़ने से पहले MainPID की value को नोट कर लें।
systemd-cgls --unit=app.service
ps -o pid,ppid,stat,etime,args -p "$(systemctl show -p MainPID --value app.service)"systemd-cgls unit के cgroup में मौजूद हर process को list करता है। ps line उस एकमात्र process का वर्णन करती है जिसे systemd supervise करता है। दोनों को एक साथ पढ़ें। MainPID का 0 होने का मतलब है कि systemd के पास monitor करने के लिए कोई process नहीं है। यदि cgroup में आपका daemon मौजूद है और MainPID एक shell को resolve करता है, तो यह ऊपर बताया गया wrapper case है। यदि cgroup में आपकी अपेक्षा से अधिक processes हैं, तो इसका मतलब है कि कोई launcher या forking daemon शामिल है।
systemctl status app.service
journalctl -u app.service -bsystemctl status state line और cgroup tree को एक साथ print करता है, इसलिए यह अक्सर दोनों सवालों के जवाब एक साथ दे देता है। -b के साथ केवल इस boot तक सीमित journalctl -u उन start और stop events को दिखाता है जिन्हें systemd ने unit के लिए record किया है, साथ ही उन exit codes को भी जिन्हें उसने देखा। यदि daemon journal के बजाय अपनी log file में लिखता है, तो उस file को भी पढ़ें, क्योंकि systemd केवल उसी को record कर सकता है जो उस तक पहुँचा है।
जब आप Type= को बदलें, तो reload और restart करें।
systemd-analyze verify /etc/systemd/system/app.service
sudo systemctl daemon-reload
sudo systemctl restart app.servicesystemd-analyze verify file को parse करता है और उन settings की रिपोर्ट करता है जिन्हें वह स्वीकार नहीं कर सकता। daemon-reload systemd को disk से unit files को फिर से read करने के लिए कहता है। बदला हुआ Type= पहले से चल रही unit पर लागू नहीं होता है, इसलिए restart अनिवार्य है, वैकल्पिक नहीं।
फिर बदलाव का परीक्षण करें। systemd-cgls से उस process का PID लें जिसकी आपको वास्तव में परवाह है और उसे kill कर दें। उसके तुरंत बाद systemctl is-active app.service चलाएँ। यदि Type= सही है, तो unit active state से बाहर हो जाएगी। यदि यह active रहती है, तो systemd अभी भी किसी और चीज़ को monitor कर रहा है।
आपको systemd service का कौन सा Type= उपयोग करना चाहिए
- ऐसा प्रोग्राम जो foreground में रहता है:
Type=exec। - ऐसा प्रोग्राम जो readiness notification का समर्थन करता है:
Type=notify, और यदि यह reloads की भी पुष्टि करता है तोnotify-reload। - एक daemon जो background में जाने पर जोर देता है:
PIDFile=के साथType=forking, याType=execके साथ इसका foreground switch। - एक script जो काम करती है और exit हो जाती है:
Type=oneshot, और यदि उद्देश्य state को पीछे छोड़ना हो तो साथ मेंRemainAfterExit=yes। - एक launcher जो exit हो जाता है जबकि उसके children चलते रहते हैं:
ExitType=cgroupके साथType=simple।
यदि आप सुनिश्चित नहीं हैं कि किसी third party daemon को किसकी आवश्यकता है, तो पहले उसकी packaged unit file पढ़ें। distribution द्वारा प्रदान की गई unit पर systemctl cat चलाने से वह Type= दिखता है जिसे upstream ने चुना है, और उस विकल्प का परीक्षण आपसे कहीं अधिक लोगों द्वारा किया गया है।
FAQ
प्रोसेस के बंद होने के बाद भी मेरी systemd unit active क्यों रहती है?
क्योंकि वह प्रोसेस जिसे systemd मुख्य प्रोसेस मानता है, अभी भी जीवित है। systemd हर service के लिए Type= के अनुसार चुनी गई एक ही PID पर नजर रखता है, न कि unit के cgroup में मौजूद हर प्रोसेस पर। Type=simple के साथ शुरू की गई wrapper script इसका सामान्य कारण है: shell ही मुख्य PID होती है, इसलिए जब shell द्वारा background में शुरू किया गया daemon बंद हो जाता है, तब भी unit active बनी रहती है। systemctl show -p MainPID app.service चलाएं, फिर systemd-cgls --unit=app.service के साथ unit का cgroup लिस्ट करें, और दोनों की तुलना करें।
Type=simple और Type=exec के बीच क्या अंतर है?
Type=simple यह मानता है कि unit तब शुरू हो गई है जैसे ही systemd ने प्रोसेस बना ली है, binary के execute होने से पहले ही। इसलिए ExecStart= में गलत path होने पर भी start job सफल दिखाई देता है और उसके बाद failure आता है। Type=exec तब तक इंतजार करता है जब तक execution सफल न हो जाए, ताकि failure की सूचना start job द्वारा ही मिल जाए। दोनों ही एक ही प्रोसेस को मुख्य PID मानते हैं। Type=exec के लिए systemd 240 या उससे नया version चाहिए।
क्या मुझे Type=forking के साथ अभी भी PIDFile= की आवश्यकता है?
हाँ, जब भी daemon इसे लिखता है। इसके बिना, systemd GuessMainPID= पर वापस चला जाता है, जो केवल एक अनुमान है और केवल उन services के लिए विश्वसनीय है जो एक ही प्रोसेस में स्थिर हो जाती हैं। जब यह अनुमान गलत या असंभव होता है, तो उस unit के लिए failure detection और automatic restarting काम करना बंद कर देते हैं। PIDFile= को उस सटीक path पर point करें जिसे daemon लिखता है, जो सामान्यतः /run के अंतर्गत होता है।
मुझे RemainAfterExit=yes का उपयोग कब करना चाहिए?
जब unit का उद्देश्य किसी प्रोसेस को चालू रखना नहीं, बल्कि system state को बदलना हो। एक Type=oneshot unit जो firewall rules लोड करती है या container stack शुरू करती है, अपना काम पूरा होते ही exit हो जाती है। RemainAfterExit=yes के बिना unit inactive हो जाती है, जिससे systemctl stop के पास रोकने के लिए कुछ नहीं बचता और ExecStop= cleanup चलाने का कोई तरीका नहीं रहता। इसके साथ, unit बिना किसी प्रोसेस के active बनी रहती है, और यहाँ यही अपेक्षित है।
क्या Type= बदलने के लिए daemon-reload की आवश्यकता होती है?
हाँ, और unit को restart करने की भी। systemctl daemon-reload systemd को disk पर मौजूद unit files को फिर से पढ़ने के लिए कहता है, लेकिन एक चल रही instance उसी Type= के साथ बनी रहती है जिसके साथ वह शुरू हुई थी। परीक्षण करने से पहले sudo systemctl daemon-reload और फिर sudo systemctl restart app.service चलाएं, अन्यथा आप अभी भी पुराने supervision व्यवहार को ही देख रहे होंगे।