Linux VPSలో systemd serviceని ఎలా క్రియేట్ చేయాలి?
మీ ప్రోగ్రామ్ సర్వర్ బూట్ అయినప్పుడు ఆటోమేటిక్గా రన్ అవ్వడానికి systemd service ఫైల్ను ఎలా రాయాలో తెలుసుకోండి. క్రాష్ అయినప్పుడు రీస్టార్ట్ చేయడం మరియు లాగ్స్ నిర్వహణపై పూర్తి గైడ్.
systemd service అంటే ఏమిటి మరియు అది మీకు ఎందుకు అవసరం
systemd service అనేది ఒక చిన్న టెక్స్ట్ ఫైల్. ఇది మీ సర్వర్లో ఒక ప్రోగ్రామ్ను ఎలా రన్ చేయాలో చెబుతుంది: సర్వర్ బూట్ అయినప్పుడు దాన్ని ప్రారంభించడం, అది క్రాష్ అయితే రీస్టార్ట్ చేయడం మరియు దాని అవుట్పుట్ను సిస్టమ్ లాగ్కు పంపడం వంటివి చేస్తుంది. దీని పని ఇంతే. మీరు SSH సెషన్లో మాన్యువల్గా ప్రారంభించే ప్రోగ్రామ్, మీరు లాగ్ అవుట్ అయినప్పుడు లేదా సర్వర్ రీబూట్ అయినప్పుడు ఆగిపోతుంది. కానీ systemd service లో ఉన్న ప్రోగ్రామ్ నిరంతరాయంగా రన్ అవుతుంది, ఎందుకంటే దాన్ని మీ షెల్ కాకుండా సర్వరే స్వయంగా నిర్వహిస్తుంది.
Ubuntu, Debian, Fedora మరియు చాలా ఆధునిక Linux సర్వర్లలో systemd అనేది init సిస్టమ్. ఇది ప్రారంభమయ్యే మొదటి ప్రాసెస్ మరియు మిగిలిన అన్నింటినీ పర్యవేక్షిస్తుంది. ఇది ఎప్పుడూ ఇలాగే లేదు, కాబట్టి unit file ఏమి చేస్తుందో తెలిసిన తర్వాత systemd అంతకుముందు ఉన్న init scripts ను ఎలా భర్తీ చేసింది అనే విషయం చదవడం ఉపయోగకరంగా ఉంటుంది. మీరు ఒక service file రాసినప్పుడు, మీ ప్రోగ్రామ్ను ఆ పర్యవేక్షకుడికి (supervisor) అప్పగిస్తారు. ఈ గైడ్ పని చేసే అతి చిన్న unit ను, ప్రతి unit లో ఉండే మూడు విభాగాలను, దాన్ని ఎలా ఆన్ చేయాలో మరియు దాని లాగ్లను ఎలా చదవాలో, timer తో షెడ్యూల్ ప్రకారం ఎలా రన్ చేయాలో, మరియు వీలైనంత తక్కువ అధికారాలతో (privilege) అది రన్ అయ్యేలా ఎలా భద్రపరచాలో వివరిస్తుంది.
పనిచేసే అతి చిన్న సర్వీస్
ఒక సర్వీస్ ఫైల్ /etc/systemd/system/ లో ఉంటుంది, .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 అనేది రన్ చేయాల్సిన కమాండ్. WantedBy=multi-user.target అంటే సర్వర్ సాధారణ multi-user ఆపరేషన్కు చేరుకున్నప్పుడు దీన్ని ప్రారంభించాలని అర్థం, దీనివల్లనే ఇది బూట్ సమయంలో ఆటోమేటిక్గా వస్తుంది. మిగిలినవన్నీ కేవలం మెరుగుదలలు మాత్రమే.
మూడు విభాగాలు మరియు వాటి ఉపయోగాలు
ప్రతి unit file చతురస్రాకార బ్రాకెట్లలోని విభాగాలగా విభజించబడి ఉంటుంది. ఒక service మూడు విభాగాలను ఉపయోగిస్తుంది.
[Unit] అనేది service ని మరియు దాని సంబంధాలను వివరిస్తుంది. మీరు ఎక్కువగా ఉపయోగించే రెండు లైన్లు ఇవే:
[Unit]
Description=My application
After=network-online.target
Wants=network-online.targetDescription అనేది systemctl status లో మీరు చూసే మానవ-అర్థమయ్యే లేబుల్. After=network-online.target అనేది నెట్వర్క్ సిద్ధంగా ఉండే వరకు మీ ప్రోగ్రామ్ను ప్రారంభించవద్దని systemd కి చెబుతుంది. ఇది పోర్ట్ను bind చేసే లేదా బయటకు కనెక్షన్ను ఏర్పరిచే దేనికైనా చాలా ముఖ్యం.
[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 ప్రాసెస్ ఫోర్గ్రౌండ్లోనే ఉంటుందని భావిస్తుంది. ఒక ప్రోగ్రామ్ బ్యాక్గ్రౌండ్లోకి ఫోర్క్ (fork) అయితే, దానికి అది ప్రారంభమయ్యే విధానానికి తగిన Type= అవసరం, లేకపోతే అసలైన daemon ఇప్పటికే ఆగిపోయినా, unit మాత్రం active అని చూపిస్తుంది. Restart=on-failure మరియు RestartSec=5 గురించి కింద ప్రత్యేక విభాగంలో తెలుసుకుందాం, ఎందుకంటే చాలామంది service ని రాసేది వీటి కోసమే.
[Install] అనేది మీరు service ని enable చేసినప్పుడు ఏమి జరుగుతుందో తెలియజేస్తుంది:
[Install]
WantedBy=multi-user.targetWantedBy=multi-user.target అనేది మీరు systemctl enable రన్ చేసినప్పుడు service ని బూట్ ప్రాసెస్కు అనుసంధానిస్తుంది. [Install] విభాగం లేకపోతే, service ని మాన్యువల్గా ప్రారంభించవచ్చు కానీ reboot తర్వాత అది స్వయంచాలకంగా ప్రారంభం కాదు.
సేవను ప్రారంభించి పర్యవేక్షించడం
ఏదైనా unit file రాసినా లేదా సవరించినా, మార్పులను systemd గుర్తించేలా reload చేయాలి. ఆ తర్వాత సేవను enable చేసి, ప్రారంభించడానికి ఈ కింది కమాండ్ వాడండి:
sudo systemctl daemon-reload
sudo systemctl enable --now myapp.servicedaemon-reload అనేది చాలామంది మర్చిపోయే ముఖ్యమైన దశ: systemd unit files ను cache చేస్తుంది, కాబట్టి మీరు reload చేసే వరకు చేసిన మార్పులు అమలులోకి రావు. enable --now కమాండ్ సేవను 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 అనేవి మీరు చూడాల్సిన స్థితి సూచికలు. ప్రోగ్రామ్ అవుట్పుట్ను చదవడానికి, ఈ నిర్దిష్ట unit కోసం journal ను ఇలా అడగండి:
sudo journalctl -u myapp.service -f-f కమాండ్ tail -f లాగానే, కొత్తగా వచ్చే లైన్లను ఎప్పటికప్పుడు చూపిస్తుంది. మీ ప్రోగ్రామ్ standard output లేదా standard error కు పంపే ఏదైనా సమాచారం ఇక్కడ కనిపిస్తుంది; దీని కోసం మీరు ప్రత్యేకంగా ఎటువంటి logging setup చేయనవసరం లేదు.
వైఫల్యం చెందినప్పుడు రీస్టార్ట్ చేయడం, మీరు ఇక్కడ ఉండటానికి కారణం
ఒక సర్వీస్ యొక్క ప్రధాన ప్రయోజనం ఏమిటంటే, మీ ప్రోగ్రామ్ ఆగిపోయినప్పుడు systemd దానిని తిరిగి ప్రారంభిస్తుంది. దీని కోసం రెండు లైన్లు సరిపోతాయి:
[Service]
Restart=on-failure
RestartSec=5Restart=on-failure అనేది ప్రోగ్రామ్ సున్నా కాని కోడ్తో నిష్క్రమించినప్పుడు లేదా SIGKILL లేదా SIGSEGV వంటి క్రాష్ సిగ్నల్స్ వల్ల ఆగిపోయినప్పుడు దానిని తిరిగి ప్రారంభిస్తుంది. క్లీన్ ఎగ్జిట్, లేదా SIGTERM, SIGINT, SIGHUP, లేదా SIGPIPE ద్వారా ఆగిపోవడం దీనిని ప్రేరేపించదు. RestartSec=5 ప్రయత్నాల మధ్య ఐదు సెకన్ల సమయం తీసుకుంటుంది, తద్వారా వెంటనే క్రాష్ అయ్యే ప్రోగ్రామ్ వేగవంతమైన లూప్లో తిరగకుండా ఉంటుంది. ప్రాసెస్ను కిల్ చేసి, systemd దానిని తిరిగి తీసుకురావడం గమనించడం ద్వారా దీనిని నిర్ధారించుకోండి. SIGKILL ఉపయోగించండి: డిఫాల్ట్ SIGTERM అనేది క్లీన్ స్టాప్గా పరిగణించబడుతుంది, కాబట్టి on-failure సర్వీస్ను రీస్టార్ట్ చేయదు:
sudo systemctl kill -s SIGKILL myapp.service
sudo systemctl status myapp.serviceఐదు సెకన్లలోపు, స్టేటస్ కొత్త Main PID మరియు మళ్ళీ active (running)ని చూపిస్తుంది. ఇది మొత్తం ఫీచర్, మరియు అందుకే ప్రోగ్రామ్ను tmux లేదా screenలో రన్ చేయడం కంటే సర్వీస్గా ఉంచడం ఉత్తమం.
అన్ప్రివిలేజ్డ్ యూజర్గా రన్ చేయండి మరియు హార్డెన్ చేయండి
ఒక ప్రోగ్రామ్ ఎప్పుడైనా ఎక్స్ప్లాయిట్ (exploit) చేయబడితే, root యూజర్గా రన్ అయ్యే సర్వీస్ మీ సర్వర్కు ఏదైనా హాని చేయగలదు. కాబట్టి, దానిని ప్రత్యేక యూజర్గా రన్ చేయండి మరియు దానిని నియంత్రించడానికి systemd కి కొన్ని ఆదేశాలను ఇవ్వండి. ముందుగా లాగిన్ మరియు హోమ్ డైరెక్టరీ లేని ఒక సిస్టమ్ అకౌంట్ను సృష్టించండి:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin myappతర్వాత User=myapp ని సెట్ చేయండి మరియు [Service] కి హార్డెనింగ్ లైన్లను జోడించండి:
[Service]
User=myapp
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=trueప్రతి లైన్ ప్రోగ్రామ్కు అవసరం లేని ఒక ఫీచర్ను తొలగిస్తుంది. NoNewPrivileges=true, setuid బైనరీ ద్వారా కూడా ప్రాసెస్ కొత్త ప్రివిలేజ్లను పొందకుండా ఆపుతుంది. PrivateTmp=true, ఇతర ప్రాసెస్లు చూడలేని ఒక ప్రైవేట్ /tmp ని ఇస్తుంది. ProtectSystem=strict, ReadWritePaths= తో మీరు పేర్కొన్న కొన్ని పాత్లు మినహా మొత్తం ఫైల్సిస్టమ్ను రీడ్-ఓన్లీగా మారుస్తుంది. ProtectHome=true, /home ని దాని నుండి పూర్తిగా దాచిపెడుతుంది. ఇది ఒక సర్వీస్ను ఫైర్వాల్ వెనుక ఉంచడం వంటి కనిష్ట-ప్రివిలేజ్ (least-privilege) ఆలోచనా విధానమే: దానికి అవసరమైనవి మాత్రమే ఇవ్వండి. మీరు VPS పై IPv6 ఫైర్వాల్ గ్యాప్ను మూసివేయడం గురించిన గైడ్ను చదివినట్లయితే, ఇది అదే ఆలోచనకు సంబంధించిన ఆన్-హోస్ట్ భాగం. ఇంటర్నెట్కు అందుబాటులో ఉండే సర్వీస్ కోసం, ఈ హార్డెనింగ్ను SSH ముందు Fail2ban మరియు డిఫాల్ట్-deny ఫైర్వాల్తో కలిపి వాడండి.
వీటన్నింటినీ మాన్యువల్గా టైప్ చేసి ఏదైనా ఆదేశాన్ని మర్చిపోయే ప్రమాదం కంటే, పూర్తిస్థాయిలో హార్డెన్ చేసిన యూనిట్ను జనరేట్ చేసి కాపీ చేసుకోండి:
Timers: ఆధునిక cron
systemd timer ఒక నిర్దిష్ట సమయపట్టిక ప్రకారం సేవను (service) నడుపుతుంది, ఇది cron job కు ఆధునిక ప్రత్యామ్నాయం. ఒక timer రెండు ఫైళ్లను కలిగి ఉంటుంది: పనిని చేసే .service మరియు ఎప్పుడు జరగాలో చెప్పే .timer. ఉదాహరణకు, ప్రతిరోజూ ఉదయం 3 గంటలకు బ్యాకప్ కావాలనుకుంటే, ఆ సేవ పనిని ఒకసారి పూర్తి చేసి నిష్క్రమిస్తుంది:
# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.shType=oneshot అనేది ప్రోగ్రామ్ రన్ అయ్యి, పూర్తయి, ఆగిపోతుందని systemd కి తెలియజేస్తుంది, ఇది నిరంతరం రన్ అవ్వదు. Timer దీనిని ఇలా షెడ్యూల్ చేస్తుంది:
# /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" తో పరీక్షించండి, ఇది అది సరిగ్గా పార్స్ అయ్యిందో లేదో నిర్ధారించి, తదుపరి రన్ అయ్యే సమయాలను చూపుతుంది. సర్వర్ ఉదయం 3 గంటలకు ఆఫ్లో ఉండి ఉంటే, Persistent=true ఆ మిస్ అయిన జాబ్ను సర్వర్ తిరిగి ఆన్ అవ్వగానే రన్ చేస్తుంది, ఇది cron లో సాధ్యం కాదు. Timer ను multi-user.target ద్వారా కాకుండా, timers.target ద్వారా ఎనేబుల్ చేయాలని గమనించండి. సేవను కాకుండా, timer ను ఎనేబుల్ చేయండి:
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timerslist-timers ప్రతి timer ను, దాని తదుపరి మరియు గత రన్ సమయాలతో సహా చూపుతుంది, కాబట్టి మీ జాబ్ ఎప్పుడు రన్ అవుతుందో మీరు ఒకే చూపులో చూడవచ్చు. మీరు timer మోడ్ను ఆన్ చేసినప్పుడు, పైన పేర్కొన్న జనరేటర్ మీ కోసం జత చేయబడిన .service మరియు .timer లను నిర్మిస్తుంది. Cron లైన్తో పోలిస్తే, timer మీకు journal లో పూర్తి logs ను, ఏదైనా సేవకు ఉండే భద్రతా నియమాలను (hardening directives), మరియు Persistent=true అందించే మిస్ అయిన రన్లను తిరిగి నిర్వహించే సౌలభ్యాన్ని ఇస్తుంది. సాధారణ జాబ్లకు cron సరిపోతుంది; కానీ జాబ్ ముఖ్యమైనదైతే timer మెరుగైన సాధనం.
FAQ
systemd service మరియు cron job మధ్య తేడా ఏమిటి?
ఒక service సుదీర్ఘకాలం నడిచే ప్రోగ్రామ్ను నిరంతరం రన్ అయ్యేలా చూస్తుంది: ఇది boot సమయంలో ప్రారంభమవుతుంది, విఫలమైతే తిరిగి పునఃప్రారంభమవుతుంది మరియు logs ను journal లో భద్రపరుస్తుంది. ఒక cron job నిర్ణీత సమయంలో ఒక చిన్న కమాండ్ను రన్ చేసి ముగుస్తుంది. మీకు షెడ్యూలింగ్తో పాటు journal logs, భద్రతా ప్రమాణాలు (hardening) మరియు మిస్ అయిన రన్లను తిరిగి పూర్తి చేసే సామర్థ్యం కావాలంటే, systemd timer ను ఉపయోగించండి. ఇది .timer షెడ్యూల్ను oneshot service తో జత చేస్తుంది మరియు చాలా సర్వర్ పనుల కోసం cron కు ప్రత్యామ్నాయంగా పనిచేస్తుంది.
నా systemd service ఫైల్ను ఎక్కడ ఉంచాలి?
మీ స్వంత unit ఫైళ్లను /etc/systemd/system/ లో ఉంచండి, వాటి పేరు .service తో ముగియాలి. ఆ డైరెక్టరీ అడ్మినిస్ట్రేటర్ జోడించే unit ఫైళ్ల కోసం ఉద్దేశించబడింది, మరియు ఇది /lib/systemd/system/ లో ప్యాకేజీల ద్వారా వచ్చే unit ఫైళ్ల కంటే ఎక్కువ ప్రాధాన్యతను కలిగి ఉంటుంది. అక్కడ ఒక ఫైల్ను సృష్టించినా లేదా సవరించినా, systemd ఆ మార్పులను గుర్తించడానికి sudo systemctl daemon-reload ను రన్ చేయండి.
ఒక service క్రాష్ అయినప్పుడు అది తిరిగి ప్రారంభమయ్యేలా ఎలా చేయాలి?
[Service] విభాగంలో Restart=on-failure మరియు RestartSec=5 లను జోడించండి, ఆపై sudo systemctl daemon-reload ను రన్ చేసి service ను రీస్టార్ట్ చేయండి. ప్రోగ్రామ్ సున్నా కాని exit code తో ముగిసినా లేదా క్రాష్ సిగ్నల్ వల్ల ఆగిపోయినా, systemd దానిని తిరిగి ప్రారంభిస్తుంది, ప్రతి ప్రయత్నం మధ్య ఐదు సెకన్ల విరామం తీసుకుంటుంది. దీనిని sudo systemctl kill -s SIGKILL myapp.service తో పరీక్షించండి; డిఫాల్ట్ సిగ్నల్ అయిన SIGTERM ఒక క్లీన్ స్టాప్గా పరిగణించబడుతుంది మరియు ఇది on-failure ను ట్రిగ్గర్ చేయదు, ఆపై systemctl status లో కొన్ని సెకన్లలో కొత్త PID కనిపిస్తుందో లేదో గమనించండి.
systemd service ను root కాని వినియోగదారుగా ఎలా రన్ చేయాలి?
sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp తో ఒక system account ను సృష్టించండి, ఆపై [Service] విభాగంలో User=myapp ను జోడించండి. ప్రాసెస్ తనకు అవసరమైనంత తక్కువ యాక్సెస్తో మాత్రమే రన్ అవ్వడానికి NoNewPrivileges=true, PrivateTmp=true, మరియు ProtectSystem=strict లను జోడించండి. ఒక service భద్రతను మెరుగుపరచడానికి మీరు చేయగలిగే అత్యంత ముఖ్యమైన మార్పు, దానిని తక్కువ అధికారాలు కలిగిన (unprivileged) వినియోగదారుగా రన్ చేయడమే.
నా service ఎందుకు ప్రారంభం కాలేదు?
సారాంశం కోసం systemctl status myapp.service ను మరియు పూర్తి వివరాల కోసం journalctl -u myapp.service ను రన్ చేయండి. సాధారణంగా వచ్చే సమస్యలు: ExecStart లో తప్పు పాత్ ఉండటం, ఏదైనా WorkingDirectory లేకపోవడం, User= ఫైల్ను చదవలేకపోవడం వల్ల వచ్చే పర్మిషన్ ఎర్రర్, లేదా ఎడిటింగ్ తర్వాత sudo systemctl daemon-reload ను రన్ చేయడం మర్చిపోవడం. journal లో ప్రోగ్రామ్ యొక్క సొంత ఎర్రర్ మెసేజ్ కనిపిస్తుంది, ఇది సాధారణంగా సమస్యను నేరుగా తెలియజేస్తుంది.