SSD Nodes Learn
मार्गदर्शक Matt Connorद्वारे Matt Connor · अपडेटेड 2026-07-24

VPS वर systemd service कशी तयार करावी

तुमचा program boot झाल्यावर आपोआप सुरू करण्यासाठी आणि crash झाल्यास restart करण्यासाठी systemd service कशी तयार करावी आणि logs कसे पाहावे याचे मार्गदर्शन.

systemd service म्हणजे काय आणि त्याची गरज का आहे

systemd service ही एक लहान text file असते जी तुमच्या server ला एखादा program कसा चालवायचा हे सांगते: boot झाल्यावर तो सुरू करणे, crash झाल्यास पुन्हा सुरू करणे (restart), आणि त्याचा output system log मध्ये पाठवणे. तिचे काम इतकेच असते. SSH session मध्ये तुम्ही स्वतः सुरू केलेला program, तुम्ही log out केल्यावर किंवा server reboot झाल्यावर लगेच बंद होतो. systemd service मध्ये असलेला program सतत चालू राहतो, कारण तो तुमच्या shell ऐवजी थेट server द्वारे नियंत्रित केला जातो.

systemd ही Ubuntu, Debian, Fedora आणि बहुतेक आधुनिक Linux servers वरील init system आहे. ही पहिली सुरू होणारी process आहे जी इतर सर्व गोष्टींवर लक्ष ठेवते (supervise करते). जेव्हा तुम्ही service file तयार करता, तेव्हा तुम्ही तुमचा program त्या supervisor कडे सोपवता. या guide मध्ये आपण: काम करणारी सर्वात लहान unit, प्रत्येक unit मधील तीन sections, service सुरू करणे आणि logs वाचणे, timer वापरून schedule वर program चालवणे, आणि कमीत कमी privileges सह सुरक्षितपणे चालवण्यासाठी ती कशी lock करायची, हे पाहणार आहोत.

सर्वात लहान कार्यरत सेवा

/etc/systemd/system/ मध्ये एक service file असते, ज्याचा विस्तार .service असा असतो आणि त्यासाठी फक्त काही ओळींची आवश्यकता असते. /usr/local/bin/myapp वरील प्रोग्रामसाठी एक फाईल तयार करा:

sudo nano /etc/systemd/system/myapp.service
[Unit]
Description=My application

[Service]
ExecStart=/usr/local/bin/myapp

[Install]
WantedBy=multi-user.target

ही एक पूर्ण आणि कार्यरत युनिट आहे. ExecStart ही रन करण्यासाठीची command आहे. WantedBy=multi-user.target म्हणजे सर्व्हर normal multi-user operation मोडमध्ये आल्यावर ही सेवा सुरू करणे, ज्यामुळे ती boot झाल्यावर आपोआप सुरू होते. इतर सर्व गोष्टी केवळ सुधारणा (refinement) आहेत.

तीन विभाग आणि त्यांचे उपयोग

प्रत्येक unit file मध्ये चौरस कंसात (square brackets) विभाग केलेले असतात. service साठी तीन विभागांचा वापर केला जातो.

[Unit] मध्ये service आणि तिचे संबंध (relationships) वर्णन केलेले असतात. तुम्ही सर्वाधिक वापरणार ओळी खालीलप्रमाणे आहेत:

[Unit]
Description=My application
After=network-online.target
Wants=network-online.target

Description हे systemctl status मध्ये दिसणारे मानवी लेबल (human label) आहे. After=network-online.target मुळे network सुरू होईपर्यंत तुमची program सुरू होणार नाही; port bind करणाऱ्या किंवा outbound connection तयार करणाऱ्या गोष्टींसाठी हे महत्त्वाचे आहे.

[Service] मध्ये program कसा रन करायचा हे ठरवले जाते. तुमचे बहुतेक settings येथे असतात:

[Service]
ExecStart=/usr/local/bin/myapp --config /etc/myapp/config.toml
WorkingDirectory=/opt/myapp
User=myapp
Restart=on-failure
RestartSec=5
Environment=LOG_LEVEL=info

User=myapp मुळे program root ऐवजी unprivileged account म्हणून रन होतो, जे सुरक्षेसाठी सर्वात महत्त्वाचे आहे. Restart=on-failure आणि RestartSec=5 यांचे स्वतःचे विभाग खालीलप्रमाणे आहेत, कारण बहुतेक लोक service लिहिण्याचे मुख्य कारण हेच असते.

[Install] मध्ये service enable केल्यावर काय घडेल हे दिले आहे:

[Install]
WantedBy=multi-user.target

WantedBy=multi-user.target मुळे systemctl enable रन केल्यावर service boot प्रक्रियेत जोडली जाते. [Install] विभागाशिवाय service मॅन्युअली सुरू करता येते, परंतु reboot नंतर ती आपोआप सुरू होणार नाही.

ते सुरू करा आणि निरीक्षण करा

कोणतीही unit file लिहिली किंवा संपादित केली की, बदल लागू करण्यासाठी systemd reload करा. त्यानंतर, एकाच टप्प्यात service enable आणि start करा:

sudo systemctl daemon-reload
sudo systemctl enable --now myapp.service

daemon-reload हा टप्पा लोक विसरतात: systemd unit files cache करते, त्यामुळे reload केल्याशिवाय संपादनामुळे काहीच फरक पडत नाही. enable --now service boot साठी enable करते आणि लगेच सुरू करते. तपासा:

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 वाचण्यासाठी, फक्त या unit साठी journal तपासा:

sudo journalctl -u myapp.service -f

-f tail -f प्रमाणे नवीन lines आल्यावर त्या फॉलो करते. तुमच्या प्रोग्रामने standard output किंवा standard error वर जे काही लिहिले आहे, ते येथे दिसते; यासाठी तुम्हाला वेगळे logging setup करण्याची गरज नाही.

Restart on failure, the reason you are here

Service चा मुख्य फायदा म्हणजे program बंद झाल्यावर systemd तो पुन्हा सुरू करते. यासाठी दोन ओळी वापरल्या जातात:

[Service]
Restart=on-failure
RestartSec=5

Restart=on-failure मुळे program जर non-zero code सह बाहेर पडले किंवा SIGKILL किंवा SIGSEGV सारख्या crash signal मुळे बंद झाले, तर तो पुन्हा सुरू होतो. जर program व्यवस्थित बंद झाले (clean exit) किंवा SIGTERM, SIGINT, SIGHUP, किंवा SIGPIPE मुळे थांबले, तर ते restart होत नाही. RestartSec=5 प्रत्येक प्रयत्नामध्ये पाच सेकंदांचा विलंब ठेवते, जेणेकरून लगेच crash होणाऱ्या program मुळे systemd सतत loop मध्ये अडकणार नाही. process kill करून आणि systemd तो पुन्हा सुरू करताना पाहून याची खात्री करा. SIGKILL वापरा: default SIGTERM हा clean stop मानला जातो, त्यामुळे on-failure service पुन्हा सुरू करणार नाही:

sudo systemctl kill -s SIGKILL myapp.service
sudo systemctl status myapp.service

पाच सेकंदांच्या आत status मध्ये पुन्हा नवीन Main PID आणि active (running) दिसून येईल. हेच या feature चे मुख्य वैशिष्ट्य आहे, आणि म्हणूनच program ला tmux किंवा screen मध्ये चालू ठेवण्यापेक्षा service वापरणे अधिक चांगले आहे.

याला unprivileged user म्हणून चालवा आणि harden करा

जर प्रोग्राममध्ये काही त्रुटी (exploit) आढळली, तर root म्हणून चालणारा service तुमच्या server वर काहीही करू शकतो. याला स्वतःच्या user द्वारे चालवा आणि systemd मध्ये काही directives वापरा जेणेकरून ते मर्यादित राहील. प्रथम, लॉगिन आणि 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 बनवते, फक्त तुम्ही ReadWritePaths= ने दिलेल्या paths सोडून. ProtectHome=true त्यापासून /home पूर्णपणे लपवते. ही 'least-privilege' संकल्पना आहे, जसे की service ला firewall च्या मागे ठेवणे: त्याला फक्त आवश्यक तेवढेच अधिकार द्या. जर तुम्ही closing the IPv6 firewall gap on a VPS वरील guide वाचला असेल, तर ही त्याच संकल्पनेची host-side अंमलबजावणी आहे. इंटरनेटशी जोडलेल्या service साठी, या hardening सोबत Fail2ban in front of SSH आणि default-deny firewall वापरा.

हे सर्व स्वतः टाईप करून एखादी directive चुकवण्यापेक्षा, एक पूर्ण आणि hardened unit तयार करा आणि ती कॉपी करा:

Toolsystemd service and timer generator

Timers: the modern cron

systemd timer ठराविक वेळेत एखादी service चालवते. हे cron job साठीचे आधुनिक पर्याय आहे. Timer मध्ये दोन files असतात: काम करण्यासाठी .timer आणि ते कधी करायचे हे सांगण्यासाठी .service. समजा तुम्हाला दररोज पहाटे 3 वाजता backup घ्यायचा आहे. service एकदा काम पूर्ण करते आणि बंद होते:

# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

Type=oneshot मुळे systemd ला समजते की program पूर्ण होऊन बंद झाला आहे, तो सतत चालू राहणार नाही. Timer त्याचे वेळापत्रक ठरवते:

# /etc/systemd/system/backup.timer
[Unit]
Description=Run the nightly backup

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target

OnCalendar=*-*-* 03:00:00 म्हणजे दररोज पहाटे 3 वाजता. कोणतीही calendar expression systemd-analyze calendar "*-*-* 03:00:00" ने तपासा; ते expression बरोबर आहे की नाही आणि पुढच्या वेळापत्रकानुसार कधी चालेल हे ते दाखवते. जर server पहाटे 3 वाजता बंद असेल, तर Persistent=true मुळे server सुरू होताच ते missed job चालवले जाते; cron मध्ये ही सुविधा नाही. लक्षात घ्या की timer timers.target द्वारे enable केला जातो, multi-user.target द्वारे नाही. service ऐवजी timer enable करा:

sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers

list-timers सर्व timers आणि त्यांच्या पुढच्या व मागील वेळेची माहिती दाखवते, ज्यामुळे पुढची वेळ लगेच समजते. वरील generator timer mode सुरू केल्यावर तुमच्यासाठी .service आणि .timer तयार करते. cron च्या तुलनेत, timer तुम्हाला journal मध्ये प्रत्यक्ष logs देते, सर्व service प्रमाणेच hardening directives देते आणि Persistent=true मुळे missed-run catch-up ची सुविधा देते. साध्या कामासाठी cron ठीक आहे; पण महत्त्वाच्या कामांसाठी timer हे अधिक चांगले साधन आहे.

FAQ

systemd service आणि cron job मधील फरक काय आहे?

Service प्रोग्राम दीर्घकाळ चालू ठेवते: ते boot झाल्यावर सुरू होते, failure आल्यास restart होते आणि journal मध्ये logs नोंदवते. Cron job एका ठराविक वेळापत्रकानुसार (schedule) छोटी command चालवते आणि नंतर बंद होते. जर तुम्हाला scheduling सोबत journal logs, hardening आणि missed runs साठी catch-up हवे असेल, तर systemd timer वापरा. हे .timer schedule आणि oneshot service एकत्र वापरते आणि बहुतेक server tasks साठी cron ची जागा घेते.

मी माझी systemd service file कुठे ठेवली पाहिजे?

तुमच्या स्वतःच्या units /etc/systemd/system/ मध्ये ठेवा, ज्याचे नाव .service ने संपलेले असावे. ते directory administrator ने जोडलेल्या units साठी आहे आणि /lib/systemd/system/ मधील packages ने दिलेल्या units पेक्षा त्याला प्राधान्य (priority) असते. तिथे file तयार किंवा edit केल्यानंतर, systemd ने बदल स्वीकारण्यासाठी sudo systemctl daemon-reload चालवा.

service crash झाली तर ती पुन्हा restart कशी करायची?

[Service] section मध्ये Restart=on-failure आणि RestartSec=5 जोडा, त्यानंतर sudo systemctl daemon-reload चालवा आणि service restart करा. जेव्हा program non-zero code सह बाहेर पडते किंवा crash signal मुळे बंद होते, तेव्हा systemd ते पुन्हा सुरू करते; प्रत्येक प्रयत्नामध्ये पाच सेकंदांचा विलंब (wait) ठेवला जातो. sudo systemctl kill -s SIGKILL myapp.service ने याची चाचणी घ्या — SIGTERM (default signal) हा clean stop मानला जातो आणि on-failure trigger करत नाही — आणि काही सेकंदात systemctl status मध्ये नवीन PID दिसतो का ते तपासा.

मी systemd service non-root user म्हणून कशी चालवू शकतो?

sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp वापरून एक system account तयार करा, त्यानंतर [Service] section मध्ये User=myapp जोडा. Process ला आवश्यक तेवढीच access मिळावी यासाठी NoNewPrivileges=true, PrivateTmp=true आणि ProtectSystem=strict जोडा. Unprivileged user म्हणून चालवणे हा service च्या सुरक्षेसाठी केलेला सर्वात महत्त्वाचा बदल आहे.

माझी service start का झाली नाही?

summary साठी systemctl status myapp.service आणि पूर्ण output साठी journalctl -u myapp.service चालवा. सर्वात सामान्य कारणे म्हणजे ExecStart मधील चुकीचा path, WorkingDirectory गहाळ असणे, User= मुळे file वाचता न आल्यामुळे झालेली permission error, किंवा edit केल्यानंतर sudo systemctl daemon-reload विसरणे. Journal मध्ये program चा स्वतःचा error message दिसतो, ज्यामध्ये सहसा समस्येचे नाव थेट दिलेले असते.