Maqola · 2026-08-16 · ~6 daqiqa o‘qiladi · o'rta
nohup emas, systemd: bot serverda qanday qilib 24/7 yashaydi
Mundarija
Bu qismni real voqea bilan boshlayman. Yaqinda serverga reboot berildi.
Saytlar ko'tarildi, systemd ostidagi xizmatlar ko'tarildi — lekin bitta bot
jim qoldi. Sababi oddiy ekan: u yillar oldin nohup python app.py & bilan
ishga tushirilgan va shu holicha ishlab yurgan. nohup jarayonni terminal
yopilishidan asraydi, ammo reboot'dan asramaydi. Bot o'ldi, hech qanday
ogohlantirish kelmadi, uzilishni birinchi bo'lib foydalanuvchi payqadi.
Bunday holatga qayta tushmaslik uchun bot oddiy jarayon emas, tizim xizmati bo'lishi kerak. Linux'da buning standart yo'li — systemd. Keling, Aladdin botini misol qilib, uni boshdan-oyoq systemd xizmatiga aylantiramiz.
Unit fayl: xizmatning pasporti#
systemd xizmati bitta matnli fayl bilan tavsiflanadi. Uni
/etc/systemd/system/ papkasiga qo'yamiz:
# /etc/systemd/system/aladdin_bot.service
[Unit]
Description=Aladdin Catalog Telegram Bot
# tarmoq ko'tarilmaguncha botni boshlamaymiz — aks holda birinchi
# so'rovlar "connection refused" bilan yiqiladi
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
# alohida foydalanuvchi: bot root bo'lib ishlamasligi kerak
User=botuser
WorkingDirectory=/opt/aladdin_bot
# sirlar unit faylda emas, .env faylda turadi (pastda tushuntiraman)
EnvironmentFile=/opt/aladdin_bot/.env
ExecStart=/opt/aladdin_bot/.venv/bin/python app.py
# yiqilsa — 5 soniyadan keyin o'zi turadi
Restart=always
RestartSec=5
# lekin cheksiz emas: 1 daqiqada 5 martadan ko'p yiqilsa, to'xtab turadi
# (buzuq deploy'ni cheksiz qayta urinishdan saqlaydi)
StartLimitIntervalSec=60
StartLimitBurst=5
[Install]
# multi-user.target'ga "ilingan" xizmat reboot'dan keyin avtomatik ko'tariladi
WantedBy=multi-user.target
Har satrning vazifasi izohda yozilgan, lekin uchta eng muhimini alohida
ta'kidlayman: Restart=always botni yiqilganda turg'izadi, WantedBy esa
reboot'dan keyin ishga tushiradi — ikkalasi birga bo'lgandagina bot chinakam
24/7 bo'ladi. User=botuser esa xavfsizlik odati: bot buzilsa ham, buzgan
odam root emas, oddiy foydalanuvchi huquqida qoladi.
Ishga tushirish: uch buyruq#
# unit faylni o'qitamiz (har tahrirdan keyin ham shu kerak)
sudo systemctl daemon-reload
# hozir ishga tushirish + reboot ro'yxatiga qo'shish, bitta buyruqda
sudo systemctl enable --now aladdin_bot
# holatini ko'ramiz
sudo systemctl status aladdin_bot
status chiqishida Active: active (running) va enabled so'zlarini
ko'rsangiz — bo'ldi, bot endi xizmat. enabled aynan reboot'dan keyin
ko'tarilishni anglatadi; active bo'lib turgan, lekin disabled xizmat
keyingi reboot'da yana jim qoladi — yuqoridagi voqeadagi xatoning o'zi.
Loglar: nohup.out o'rniga journalctl#
nohup davrida loglar nohup.out degan faylga oqib borardi — u nazoratsiz
o'sadi va hech kim uni o'qimaydi. systemd'da esa stdout'ga yozilgan har
narsa avtomatik jurnalga tushadi. Ya'ni bot kodida oddiy print yoki
logging.StreamHandler yetarli, fayl bilan ishlash umuman shart emas:
# jonli oqim (Ctrl+C bilan chiqiladi)
sudo journalctl -u aladdin_bot -f
# oxirgi soatdagi xatolar
sudo journalctl -u aladdin_bot --since "1 hour ago" -p err
# kecha kechqurun nima bo'lgani
sudo journalctl -u aladdin_bot --since "yesterday 18:00" --until "yesterday 23:00"
Log fayl emas, oqim
Ilova o'z logini faylga yozmasin — shunchaki stdout'ga chiqarsin, qolganini tizim hal qiladi. Bu 12-factor tamoyillaridan biri va systemd bilan u o'z-o'zidan ishlaydi: rotatsiya, saqlash muddati, qidiruv — hammasi journald zimmasida.
Sirlar: EnvironmentFile#
Bot tokeni, API kalitlari unit faylga yozilmaydi, chunki unit fayl
/etc/systemd/system/da hamma o'qiy oladigan joyda turadi. Ular alohida
faylga chiqariladi:
# /opt/aladdin_bot/.env
BOT_TOKEN=1234567890:AAF...
CATALOG_API_URL=https://catalog.misol.uz/api/telegram
# faqat egasi o'qiy oladi:
sudo chown botuser:botuser /opt/aladdin_bot/.env
sudo chmod 600 /opt/aladdin_bot/.env
EnvironmentFile= qatori tufayli bu o'zgaruvchilar botga muhit orqali
yetib boradi — kodda os.environ["BOT_TOKEN"] deb o'qiladi, fayl yo'li
haqida bot hech narsa bilmaydi.
Ishonch hosil qilish: ikkita sinov#
Sozlab bo'ldik — endi haqiqatan ishlashini tekshiramiz. Birinchi sinov, jarayonni ataylab o'ldiramiz:
sudo pkill -f "python app.py"
sleep 6
sudo systemctl status aladdin_bot # yana active (running) bo'lishi kerak
Ikkinchi sinov — reboot'ning o'zi. Buni "qachondir kerak bo'lganda" emas,
sozlagan kuningiz qiling: sudo reboot, bir daqiqadan keyin ulanib
systemctl status qarang. Ishlayaptimi — endi kechasi ham, ta'tilda ham
xotirjam uxlayverasiz. Bizning holatda aynan shu sinov qilinmagani uchun
bot yillar o'tib "jim o'lgan" edi.
Restart har dardga davo emas
Restart=always yiqilgan botni turg'izadi, lekin nega yiqilganini
aytmaydi. Bot har besh daqiqada qayta tug'ilib ishlayotgan bo'lishi ham
mumkin — tashqaridan hammasi joyida ko'rinadi. Vaqti-vaqti bilan
journalctl -u aladdin_bot -p err --since today qarab turing, yoki
yaxshisi, xatolarni adminga yuboradigan bildirishnoma qo'shing —
Humo seriyasida shunga
o'xshash yondashuvni ko'rgan edik.
Xulosa#
Botni serverda uzoq yashatishning retsepti qisqa: nohup unutiladi, o'rniga
bitta unit fayl yoziladi. Unda uchta narsa hal qiluvchi — Restart=always
(yiqilsa turadi), WantedBy=multi-user.target + enable (reboot'dan omon
chiqadi) va EnvironmentFile (sirlar o'z joyida). Loglar journalctl'da,
sinov esa sozlagan kuni qilinadi, keyinga qoldirilmaydi.
Shu bilan Aladdin bot amaliyoti seriyasi yakunlandi: backend'dan ajratilgan katalog, adashtirmaydigan navigatsiya, uch til va o'lmas xizmat — besh yildan beri ishlab turgan botning to'liq retsepti. Server sozlashning qolgan qismi — nginx, TLS, backup va boshqalar — alohida DevOps seriyasida davom etadi.