SSD Nodes Learn
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-07-24

VPS پر systemd service کیسے بنائیں

اپنے پروگرام کو VPS پر ہمیشہ چلانے کے لیے systemd service فائل لکھنا، اسے boot پر شروع کرنا اور logs دیکھنا سیکھیں۔ مکمل گائیڈ اور timer کا استعمال۔

systemd service کیا ہے، اور آپ کو اس کی ضرورت کیوں ہے

systemd service ایک چھوٹی ٹیکسٹ فائل ہوتی ہے جو آپ کے سرور کو بتاتی ہے کہ کسی پروگرام کو کیسے چلانا ہے: اسے boot کے وقت شروع کرنا، کریش ہونے کی صورت میں اسے دوبارہ شروع کرنا، اور اس کا output سسٹم log میں بھیجنا۔ اس کا کام اتنا ہی ہے۔ اگر آپ کسی پروگرام کو SSH session میں مینوئل طریقے سے شروع کرتے ہیں، تو logout کرنے یا سرور reboot ہونے پر وہ بند ہو جاتا ہے۔ جبکہ systemd service میں لپٹا ہوا پروگرام چلتا رہتا ہے، کیونکہ اسے آپ کا shell نہیں بلکہ خود سرور کنٹرول کرتا ہے۔

systemd، Ubuntu، Debian، Fedora، اور زیادہ تر جدید Linux servers کا init system ہے۔ یہ سب سے پہلا process ہے جو شروع ہوتا ہے اور باقی تمام چیزوں کی نگرانی کرتا ہے۔ جب آپ service file لکھتے ہیں، تو آپ اپنے پروگرام کو اس supervisor کے حوالے کر دیتے ہیں۔ یہ گائیڈ کام کرنے والی سب سے چھوٹی unit، ہر unit کے تین sections، اسے شروع کرنے اور اس کے logs پڑھنے کا طریقہ، timer کے ذریعے اسے ایک شیڈول پر چلانے کا طریقہ، اور اسے کم سے کم privileges کے ساتھ چلانے کے لیے محفوظ بنانے کا طریقہ بتاتی ہے۔

سب سے چھوٹا کام کرنے والا سروس

ایک سروس فائل /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 کا مطلب ہے کہ جب سرور normal multi-user operation پر پہنچ جائے تو اسے شروع کر دیں۔ یہی وہ چیز ہے جو اسے boot کے وقت شروع کرتی ہے۔ باقی تمام چیزیں صرف بہتری کے لیے ہیں۔

تین سیکشنز، اور ان کا مقصد

ہر unit file کو square brackets کے اندر موجود سیکشنز میں تقسیم کیا گیا ہے۔ ایک service تین سیکشنز استعمال کرتی ہے۔

[Unit] سروس اور اس کے تعلقات کی وضاحت کرتا ہے۔ وہ دو لائنیں جنہیں آپ سب سے زیادہ استعمال کریں گے:

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

Description وہ انسانی نام (label) ہے جو آپ کو systemctl status میں نظر آتا ہے۔ After=network-online.target systemd کو بتاتا ہے کہ جب تک نیٹ ورک آن نہ ہو جائے آپ کا پروگرام شروع نہ کرے، جو کہ ان تمام چیزوں کے لیے ضروری ہے جو کسی 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=info

User=myapp پروگرام کو root کے بجائے ایک unprivileged account کے طور پر چلاتا ہے، جو کہ حفاظت (safety) کے لیے سب سے اہم لائن ہے۔ Restart=on-failure اور RestartSec=5 کے اپنے علیحدہ سیکشنز نیچے موجود ہیں، کیونکہ زیادہ تر لوگ سروس اسی وجہ سے لکھتے ہیں۔

[Install] وہ عمل ہے جو سروس کو enable کرنے پر ہوتا ہے:

[Install]
WantedBy=multi-user.target

WantedBy=multi-user.target وہ عمل ہے جو systemctl enable چلانے پر سروس کو boot کے ساتھ منسلک کرتا ہے۔ اگر [Install] سیکشن موجود نہ ہو تو سروس کو دستی طور پر (by hand) شروع کیا جا سکتا ہے لیکن reboot کے بعد وہ خود بخود شروع نہیں ہوگی۔

اسے آن کریں اور مانیٹر کریں

کسی بھی unit file کو لکھنے یا ایڈٹ کرنے کے بعد، systemd کو reload کریں تاکہ وہ تبدیلیوں کو پڑھ سکے، پھر ایک ہی مرحلے میں سروس کو enable اور start کریں:

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

daemon-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 وہ نتائج ہیں جو آپ کو چاہیے ہوں گے۔ پروگرام کا output پڑھنے کے لیے، صرف اس مخصوص unit کے لیے journal سے پوچھیں:

sudo journalctl -u myapp.service -f

-f نئے lines کو اسی طرح فالو کرتا ہے جیسے وہ آتے ہیں، بالکل tail -f کی طرح۔ آپ کا پروگرام standard output یا standard error پر جو کچھ بھی لکھتا ہے، وہ یہاں آ جاتا ہے، اور اس کے لیے آپ کو logging setup کرنے کی ضرورت نہیں ہوتی۔

Restart on failure, the reason you are here

Service کا سب سے بڑا فائدہ یہ ہے کہ systemd آپ کے پروگرام کو دوبارہ شروع کر دیتا ہے جب وہ بند ہو جاتا ہے۔ یہ کام دو لائنیں کرتی ہیں:

[Service]
Restart=on-failure
RestartSec=5

Restart=on-failure پروگرام کو دوبارہ شروع کرتا ہے اگر وہ non-zero code کے ساتھ ختم ہو یا SIGKILL یا SIGSEGV جیسے crash signal کی وجہ سے بند ہو جائے۔ اگر پروگرام صحیح طریقے سے (clean exit) یا SIGTERM، SIGINT، SIGHUP، یا SIGPIPE کے ذریعے بند ہو، تو یہ عمل نہیں ہوگا۔ RestartSec=5 کوششوں کے درمیان 5 seconds کا وقفہ رکھتا ہے، تاکہ اگر پروگرام فوری طور پر crash ہو رہا ہو تو وہ مسلسل loop میں نہ پھنس جائے۔ اس کی تصدیق کرنے کے لیے process کو kill کریں اور دیکھیں کہ systemd اسے دوبارہ کیسے شروع کرتا ہے۔ SIGKILL استعمال کریں: کیونکہ default SIGTERM کو clean stop مانا جاتا ہے، اس لیے on-failure service کو دوبارہ شروع نہیں کرے گا:

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

5 seconds کے اندر status میں دوبارہ نیا Main PID اور active (running) نظر آئے گا۔ یہی اس فیچر کا مقصد ہے، اور یہی وجہ ہے کہ service کا استعمال پروگرام کو tmux یا screen میں چلانے سے بہتر ہے۔

اسے غیر مستحق صارف (unprivileged user) کے طور پر چلائیں، اور اسے محفوظ بنائیں

اگر پروگرام میں کوئی خرابی (exploit) پیدا ہو جائے تو root کے طور پر چلنے والی سروس آپ کے سرور پر کچھ بھی کر سکتی ہے۔ اسے اپنے مخصوص صارف کے طور پر چلائیں، اور systemd کو کچھ ایسی ہدایات دیں جو اسے محدود کر دیں۔ سب سے پہلے ایک ایسا system account بنائیں جس کا کوئی login یا home directory نہ ہو:

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

ہر لائن پروگرام کی کسی نہ کسی ضرورت کو ختم کرتی ہے۔ NoNewPrivileges=true عمل (process) کو نئی privileges حاصل کرنے سے روکتا ہے، چاہے وہ setuid binary کے ذریعے ہی کیوں نہ ہو۔ PrivateTmp=true اسے ایک private /tmp فراہم کرتا ہے جسے کوئی دوسرا process نہیں دیکھ سکتا۔ ProtectSystem=strict پورے filesystem کو read-only بنا دیتا ہے، سوائے ان چند paths کے جن کا آپ ReadWritePaths= کے ذریعے نام دیتے ہیں۔ ProtectHome=true، /home کو اس سے مکمل طور پر چھپا دیتا ہے۔ یہ وہی least-privilege سوچ ہے جو کسی سروس کو firewall کے پیچھے رکھنے کے برابر ہے: اسے صرف وہی دیں جو اسے درکار ہے۔ اگر آپ نے VPS پر IPv6 firewall gap کو بند کرنے کے بارے میں گائیڈ پڑھ لی ہے، تو یہ اسی تصور کا on-host حصہ ہے۔ انٹرنیٹ سے منسلک سروس کے لیے، اس hardening کو SSH کے سامنے Fail2ban اور default-deny firewall کے ساتھ استعمال کریں۔

تمام ہدایات کو خود ٹائپ کرنے اور کسی غلطی سے بچنے کے لیے، ایک مکمل اور hardened unit جنریٹ کریں اور اسے کاپی کر لیں:

Toolsystemd service and timer generator

Timers: the modern cron

systemd timer ایک شیڈول کے مطابق سروس کو چلاتا ہے، اور یہ cron job کا جدید متبادل ہے۔ ایک timer دو فائلوں پر مشتمل ہوتا ہے: ایک .service جو کام انجام دیتی ہے، اور ایک .timer جو وقت بتاتی ہے۔ فرض کریں کہ آپ کو روزانہ 3am پر بیک اپ چاہیے۔ سروس کام کو ایک بار مکمل کرتی ہے اور بند ہو جاتی ہے:

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

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

Type=oneshot systemd کو بتاتا ہے کہ پروگرام چل کر مکمل ہو گیا ہے، بجائے اس کے کہ وہ مستقل طور پر چلتا رہے۔ 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 کا مطلب ہے روزانہ 3am۔ کسی بھی calendar expression کو systemd-analyze calendar "*-*-* 03:00:00" کے ساتھ ٹیسٹ کریں، جو یہ تصدیق کرتا ہے کہ وہ صحیح طریقے سے پرز (parse) ہو رہا ہے اور اگلی بار چلنے کا وقت دکھاتا ہے۔ اگر سرور 3am پر بند تھا، تو Persistent=true مِس شدہ کام کو سرور کے دوبارہ آن ہوتے ہی چلا دیتا ہے، جو cron نہیں کر سکتا۔ یاد رکھیں کہ timer کو timers.target کے ذریعے enable کیا جاتا ہے، multi-user.target کے ذریعے نہیں۔ timer کو enable کریں، سروس کو نہیں۔

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

list-timers ہر timer کو اس کے اگلے اور آخری چلنے کے وقت کے ساتھ دکھاتا ہے، تاکہ آپ ایک نظر میں دیکھ سکیں کہ آپ کا کام اگلی بار کب چلے گا۔ اوپر دیا گیا generator timer mode آن کرنے پر آپ کے لیے جفت شدہ .service اور .timer خود بنا دیتا ہے۔ cron کے مقابلے میں، timer آپ کو journal میں اصل logs، کسی بھی سروس کی طرح hardening directives، اور Persistent=true کے ذریعے مِس شدہ کام کو مکمل کرنے کی سہولت دیتا ہے۔ سادہ کاموں کے لیے cron اب بھی ٹھیک ہے؛ لیکن اہم کاموں کے لیے timer ایک بہتر ٹول ہے۔

FAQ

systemd service اور cron job میں کیا فرق ہے؟

Service ایک پروگرام کو مسلسل چلتی رکھتی ہے: یہ boot پر شروع ہوتی ہے، خرابی کی صورت میں دوبارہ شروع (restart) ہوتی ہے، اور journal میں logs محفوظ کرتی ہے۔ Cron job ایک مختصر کمانڈ کو مقررہ وقت پر چلا کر ختم ہو جاتی ہے۔ اگر آپ کو scheduling کے ساتھ ساتھ journal logs، hardening، اور مس شدہ runs کے لیے catch-up کی ضرورت ہو، تو systemd timer استعمال کریں۔ یہ .timer schedule کو oneshot service کے ساتھ جوڑتا ہے اور زیادہ تر server tasks کے لیے cron کا متبادل ہے۔

میں اپنی systemd service file کہاں رکھوں؟

اپنی units کو .service نام کے ساتھ /etc/systemd/system/ میں رکھیں۔ یہ directory administrator کے شامل کردہ units کے لیے ہے، اور یہ /lib/systemd/system/ میں موجود packages کی units پر ترجیح (priority) رکھتی ہے۔ فائل بنانے یا ترمیم کرنے کے بعد، sudo systemctl daemon-reload چلائیں تاکہ systemd تبدیلی کو قبول کر لے۔

اگر service crash ہو جائے تو اسے restart کیسے کریں؟

[Service] section میں Restart=on-failure اور RestartSec=5 شامل کریں، پھر sudo systemctl daemon-reload چلائیں اور service کو restart کریں۔ جب پروگرام non-zero code کے ساتھ ختم ہوتا ہے یا crash signal سے بند ہوتا ہے، تو systemd اسے دوبارہ چلا دیتا ہے، اور کوششوں کے درمیان 5 seconds کا وقفہ رکھتا ہے۔ اسے sudo systemctl kill -s SIGKILL myapp.service کے ساتھ test کریں — SIGTERM، جو کہ default signal ہے، ایک clean stop سمجھا جاتا ہے اور on-failure کو trigger نہیں کرتا — اور دیکھیں کہ systemctl status چند seconds میں نیا PID دکھاتا ہے۔

میں systemd service کو non-root user کے طور پر کیسے چلا سکتا ہوں؟

sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp کے ذریعے ایک system account بنائیں، پھر [Service] section میں User=myapp شامل کریں۔ NoNewPrivileges=true، PrivateTmp=true، اور ProtectSystem=strict شامل کریں تاکہ process کو صرف ضروری access ملے۔ unprivileged user کے طور پر چلانا کسی بھی service کی safety کے لیے سب سے اہم تبدیلی ہے۔

میری service start کیوں نہیں ہوئی؟

Summary کے لیے systemctl status myapp.service اور مکمل output کے لیے journalctl -u myapp.service چلائیں۔ عام وجوہات میں ExecStart میں غلط path، WorkingDirectory کا نہ ہونا، permission error کیونکہ User= فائل نہیں پڑھ سکتا، یا ترمیم کے بعد sudo systemctl daemon-reload کا بھول جانا شامل ہے۔ journal پروگرام کا اپنا error message دکھاتا ہے، جو عام طور پر مسئلے کا نام براہ راست بتاتا ہے۔