systemd — xizmatlar, systemctl, o'z xizmatingizni yozish

~18 daq · Linux · Jarayonlar va tizim

Muammodan boshlaylik

Node.js API ni serverda ishga tushirdingiz: nohup node server.js &. Ishlayapti. Lekin:

  • Kechasi ilova qulab tushdi — ertalabgacha sayt ishlamadi
  • Hosting serverni yangilanish uchun qayta yukladi — ilova ishga tushmadi
  • Loglar qayerda? nohup.out da, cheksiz o'sib bormoqda
  • Ilova root sifatida ishlayapti

Nginx, MySQL esa bunday muammolarsiz ishlaydi: server yuklanganda o'zi ishga tushadi, qulasa — qayta ko'tariladi. Ularni systemd boshqaradi. O'z ilovangizni ham shunday qilish — 15 qatorlik fayl.


systemd nima?

systemd — zamonaviy Linux ning PID 1 jarayoni (22-dars): yadro yuklanganidan keyin birinchi ishga tushadigan va qolgan hamma narsani boshqaradigan dastur. U:

  • Xizmatlarni to'g'ri tartibda ishga tushiradi (avval tarmoq, keyin baza, keyin ilova)
  • Qulagan xizmatlarni qayta ishga tushiradi
  • Loglarni yig'adi (journalctl, 26-dars)
  • Rejalashtirilgan vazifalarni bajaradi (timer lar, 40-dars)

Har bir boshqariladigan narsa — unit. Xizmatlar — .service unit lari.


systemctl — xizmatlarni boshqarish

systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Fri 2026-11-06 09:00:12 +05; 5h ago
       Docs: man:nginx(8)
   Main PID: 1102 (nginx)
      Tasks: 3 (limit: 4558)
     Memory: 8.2M
        CPU: 1.204s
     CGroup: /system.slice/nginx.service
             ├─1102 "nginx: master process /usr/sbin/nginx -g daemon on;"
             └─1104 "nginx: worker process"

Nov 06 09:00:12 server systemd[1]: Started nginx.service.
  • Loaded ... enabled — server yuklanganda avtomatik ishga tushadi
  • Active: active (running) — hozir ishlayapti
  • Pastda — oxirgi log qatorlari

Asosiy buyruqlar

Buyruq Nima
sudo systemctl start nginx Ishga tushirish
sudo systemctl stop nginx To'xtatish (SIGTERM → kutish → SIGKILL)
sudo systemctl restart nginx Qayta ishga tushirish
sudo systemctl reload nginx Sozlamalarni qayta o'qish, to'xtamasdan
sudo systemctl enable nginx Yuklanishda avtomatik ishga tushirish
sudo systemctl disable nginx Avtomatik ishga tushirishni o'chirish
sudo systemctl enable --now nginx Yoqish + darhol ishga tushirish
systemctl is-active nginx active / inactive (skriptlar uchun)
systemctl is-enabled nginx enabled / disabled

[!INFO] start va enable — turli narsalar. start — hozir ishga tushirish. enable — keyingi yuklanishlarda avtomatik. Odatda ikkalasi ham kerak: enable --now.

Ro'yxatlar

systemctl list-units --type=service              # ishlayotgan xizmatlar
systemctl list-units --type=service --state=failed   # xato bilan to'xtaganlar
systemctl list-unit-files --type=service         # barcha o'rnatilganlar

--state=failed — serverda nimadir ishlamayotganda birinchi buyruq.


O'z xizmatingizni yozish

Vazifa: /opt/dokon/server.js dagi Node.js ilovani to'liq xizmatga aylantirish.

1. Alohida foydalanuvchi (18-dars)

sudo useradd --system --no-create-home --shell /usr/sbin/nologin dokon
sudo chown -R dokon:dokon /opt/dokon

2. Unit fayl

sudo nano /etc/systemd/system/dokon.service
[Unit]
Description=Dokon API
After=network.target mysql.service
Wants=mysql.service

[Service]
Type=simple
User=dokon
Group=dokon
WorkingDirectory=/opt/dokon
EnvironmentFile=/opt/dokon/.env
Environment=NODE_ENV=production
ExecStart=/usr/bin/node /opt/dokon/server.js
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

3. Ishga tushirish

sudo systemctl daemon-reload          # systemd ga yangi fayl haqida aytish
sudo systemctl enable --now dokon
systemctl status dokon

Tayyor. Endi ilova:

  • Server yuklanganda o'zi ishga tushadi (enable)
  • Qulasa — 5 soniyadan keyin qayta ko'tariladi (Restart=on-failure)
  • dokon foydalanuvchisi nomidan ishlaydi — root emas
  • Loglari — journalctl -u dokon da (26-dars)

Unit fayl tuzilishi

[Unit] — tavsif va bog'liqliklar

Kalit Ma'nosi
Description Inson uchun nom
After Shulardan keyin ishga tushirish (tartib)
Wants Shularni ham ishga tushirishga harakat qilish (yumshoq bog'liqlik)
Requires Shular albatta kerak (qattiq bog'liqlik)

[Service] — qanday ishga tushirish

Kalit Ma'nosi
ExecStart Buyruq — absolyut yo'l bilan (which node)
User, Group Kim nomidan
WorkingDirectory Qaysi papkada
Environment Muhit o'zgaruvchisi
EnvironmentFile .env fayldan o'qish
Restart on-failure — xato bilan chiqsa; always — har doim
RestartSec Qayta ishga tushirishdan oldin kutish
ExecReload reload da nima qilish (masalan, kill -HUP $MAINPID)
TimeoutStopSec SIGTERM dan keyin SIGKILL gacha kutish (standart 90s)

[Install] — enable qilinganda

WantedBy=multi-user.target — "oddiy server rejimida ishga tushirish". Deyarli har doim shu.

[!WARNING] Unit faylni o'zgartirgandan keyin har doim sudo systemctl daemon-reload, keyin restart. Aks holda systemd eski versiyani ishlatishda davom etadi va ogohlantiradi: "unit file changed on disk".


Xavfsizlikni kuchaytirish

systemd xizmatni izolyatsiya qila oladi — bir necha qator bilan:

[Service]
...
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/dokon/uploads /var/log/dokon
PrivateTmp=true
UMask=0027
  • ProtectSystem=strict — butun fayl tizimi faqat o'qish uchun
  • ReadWritePaths — faqat shu papkalarga yozish mumkin
  • ProtectHome — /home ko'rinmaydi
  • PrivateTmp — o'z alohida /tmp

Ilova buzilsa ham — hujumchi deyarli hech narsa qila olmaydi. Xavfsizlik bahosi: systemd-analyze security dokon.


Tashxis

Xizmat ishga tushmayapti:

systemctl status dokon                  # holat va oxirgi loglar
journalctl -u dokon -n 50 --no-pager    # oxirgi 50 qator log
journalctl -u dokon -f                  # jonli kuzatish

Tipik xatolar:

Xabar Sabab
status=203/EXEC ExecStart yo'li noto'g'ri yoki fayl bajariladigan emas
status=217/USER User= dagi foydalanuvchi mavjud emas
status=200/CHDIR WorkingDirectory yo'q yoki ruxsat yo'q
EACCES / Permission denied Foydalanuvchi fayllarni o'qiy olmaydi — chown (21-dars)
EADDRINUSE Port band — sudo ss -tlnp (22-dars)
Start request repeated too quickly Ilova darhol qulayapti; loglarni o'qing

Qo'lda sinash — xizmat foydalanuvchisi nomidan:

sudo -u dokon bash -c 'cd /opt/dokon && node server.js'

Nima uchun shunday?

Nima uchun systemd unit fayllari — oddiy matn, va nima uchun bu yaxshi?

Chunki deklarativ matnli fayl — tasvirlash, skript emas: "nima" ishga tushishi kerakligi va "qanday shartlar" bilan, "qanday qilib" emas. Eski tizimlarda (SysV init) har bir xizmat uchun 100+ qatorlik bash skript yozilardi — PID fayllar, qayta ishga tushirish mantiqi, log yo'naltirish — har birida o'z xatolari bilan. systemd bularning hammasini o'z zimmasiga oladi: siz faqat ExecStart va Restart ni yozasiz. Natija: qisqa, o'qiladigan, Git da saqlanadigan va har bir serverda bir xil ishlaydigan fayl. Docker Compose ning restart: unless-stopped i ham aynan shu g'oyani konteynerlar uchun takrorlaydi.


Xulosa

Eslab qoling:

  • systemd — PID 1; xizmatlarni ishga tushiradi, qayta ko'taradi, loglarni yig'adi
  • systemctl status/start/stop/restart/reload
  • enable — yuklanishda avtomatik; enable --now — yoqish + ishga tushirish
  • systemctl list-units --state=failed — nima ishlamayapti
  • O'z xizmatingiz: /etc/systemd/system/nom.service — [Unit], [Service], [Install]
  • ExecStart — absolyut yo'l; User — root emas; Restart=on-failure
  • O'zgartirgandan keyin: daemon-reload + restart
  • Tashxis: systemctl status, journalctl -u nom

Keyingi dars

26-dars: Tizim loglari — journalctl, /var/log