Кўпчилик Python ботини биринчи марта серверга жойлаганда уни SSH орқали python3 bot.py буйруғи билан ишга туширади ва ҳаммаси ишлаётганини кўриб хурсанд бўлади. Аммо терминал ойнаси ёпилиши билан ёки SSH уланиш узилиши билан бот ҳам тўхтайди. Ундан кейин nohup ёки screen синаб кўрилади, лекин сервер қайта юкланганда ёки бот хато билан йиқилганда уни ҳеч ким қайта ишга туширмайди. Ботни ҳақиқатан ҳам кеча-кундуз ишлатиш учун уни операцион тизим бошқарадиган хизматга айлантириш керак.
Нега оддий хостинг бунга мос эмас
Оддий shared хостинг асосан PHP сайтлар учун мўлжалланган: сўров келади, скрипт ишлайди ва тугайди. Доимий ишлаб турадиган жараёнлар бундай муҳитда одатда ресурс чекловлари ёки тизим томонидан тўхтатилади, cron орқали "тирик ушлаш" уринишлари ҳам ишончли натижа бермайди. Шунинг учун 24/7 ишлаши керак бўлган бот учун root ҳуқуқи бор VPS энг тўғри танлов ҳисобланади. VPS'да сиз ўзингиз systemd хизматини яратасиз ва бот тизим билан бирга ишга тушади.
Ботни тайёрлаш: алоҳида фойдаланувчи ва виртуал муҳит
Ботни root номидан ишлатиш хавфсизлик нуқтаи назаридан ёмон одат. Яхшиси, бот учун алоҳида тизим фойдаланувчиси яратиб, кодни унинг папкасига жойлаштиринг. Кутубхоналарни тизим Python'ига эмас, виртуал муҳитга ўрнатинг, шунда бошқа лойиҳалар билан версия тўқнашуви бўлмайди.
sudo adduser --system --group --home /opt/mybot mybot
sudo -u mybot python3 -m venv /opt/mybot/venv
sudo -u mybot /opt/mybot/venv/bin/pip install -r /opt/mybot/requirements.txt
Бот токени каби махфий маълумотларни код ичига ёзманг. Уларни алоҳида .env файлда сақланг ва файлга фақат бот фойдаланувчиси ўқий оладиган ҳуқуқ беринг. Бу токен тасодифан GitHub'га юкланиб кетишидан ҳам ҳимоя қилади.
sudo nano /opt/mybot/.env
# BOT_TOKEN=123456:ABC...
sudo chown mybot:mybot /opt/mybot/.env
sudo chmod 600 /opt/mybot/.env
systemd хизматини яратиш
systemd замонавий Linux тизимларида хизматларни бошқарувчи асосий восита. У жараённи ишга туширади, йиқилса қайта кўтаради, сервер юкланганда автоматик ёқади ва барча чиқишни журналга ёзади. Бунинг учун битта unit файл ёзиш кифоя.
sudo nano /etc/systemd/system/mybot.service
[Unit]
Description=Telegram bot (mybot)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=mybot
WorkingDirectory=/opt/mybot
EnvironmentFile=/opt/mybot/.env
ExecStart=/opt/mybot/venv/bin/python -u bot.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Бу ерда Restart=always бот қайси сабаб билан тўхтамасин, беш сониядан кейин уни қайта ишга туширади. -u байроғи Python чиқишини буферламайди, шунинг учун логлар журналда дарҳол кўринади. Файл тайёр бўлгач, systemd'га янги хизмат ҳақида хабар берилади ва у ёқилади.
sudo systemctl daemon-reload
sudo systemctl enable --now mybot
systemctl status mybot
Логларни кузатиш
Бот нима қилаётганини билиш учун алоҳида лог файл яратиш шарт эмас, чунки systemd барча чиқишни журналга йиғади. Қуйидаги буйруқлар охирги ёзувларни кўрсатади ёки янги ёзувларни жонли кузатиб боради. Кодни янгилаганингиздан кейин хизматни қайта ишга тушириш ҳам битта буйруқ билан бажарилади.
journalctl -u mybot -n 100
journalctl -u mybot -f
sudo systemctl restart mybot
PM2 билан ишлатиш варианти
PM2 аслида Node.js учун яратилган жараён менежери, лекин у Python скриптларини ҳам бемалол бошқаради. Агар серверда аллақачон Node.js лойиҳалари PM2 орқали ишлаётган бўлса, барча жараёнларни битта рўйхатда кўриш қулай. PM2 ўрнатиш учун серверда Node.js ва npm бўлиши керак.
sudo npm install -g pm2
cd /opt/mybot
pm2 start bot.py --name mybot --interpreter /opt/mybot/venv/bin/python
pm2 save
pm2 startup
pm2 startup буйруғи экранга битта sudo буйруғини чиқаради, уни нусхалаб бажариш керак, акс ҳолда сервер қайта юкланганда PM2 ўзи ишга тушмайди. pm2 save эса жорий жараёнлар рўйхатини сақлаб қўяди. Кейинчалик pm2 logs mybot билан логларни, pm2 restart mybot билан қайта ишга туширишни бошқарасиз.
systemd ёки PM2: қайси бирини танлаш
| Мезон | systemd | PM2 |
|---|---|---|
| Қўшимча ўрнатиш | Керак эмас, тизимда бор | Node.js ва npm керак |
| Логлар | journalctl | pm2 logs, ~/.pm2/logs |
| Бир нечта жараённи кўриш | systemctl list-units | pm2 list, pm2 monit |
| Кимга қулай | Фақат Python лойиҳалари | Node.js билан аралаш серверлар |
Фақат битта ёки иккита Python бот бўлса, systemd ортиқча боғлиқликсиз энг содда ва ишончли йўл. PM2 эса кўп лойиҳани битта панел орқали кузатишни хоҳлаганлар учун қулай.
Амалий мисол: Тошкентдаги гул дўкони боти
Фараз қилайлик, Тошкентдаги гул дўкони буюртмаларни Telegram бот орқали қабул қилади ва ҳар бир буюртмани misol.uz сайтидаги базага ёзади. Бот олдин дастурчининг ноутбукида ишлаган ва кечаси ноутбук ёпилганда буюртмалар йўқолган. Ботни кичик VPS'га кўчириб, юқоридаги systemd хизмати билан ишга туширгандан кейин у сервер билан бирга ёнади, тармоқ узилиб хато берса, беш сонияда қайта кўтарилади. Дўкон эгаси муаммо бўлганда journalctl -u mybot орқали аниқ хато матнини кўриб, дастурчига юборади.
Тез-тез учрайдиган хатолар
- Unit файлда нисбий йўл ёзиш:
ExecStartичида доим тўлиқ йўлдан фойдаланинг. - Виртуал муҳит ўрнига тизим Python'ини кўрсатиш, натижада кутубхона топилмайди деган хато чиқади.
- Битта ботни ҳам systemd, ҳам PM2 орқали бир вақтда ишга тушириш: Telegram бунда икки нусха сўровлари тўқнашуви ҳақида хато беради.
- Файл ўзгаргандан кейин
daemon-reloadқилишни унутиш.
Бот учун сервер керак бўлса, sayt.uz кабинетидан VPS буюртма қилиб, унда юқоридаги созламаларни бир неча дақиқада бажаришингиз мумкин. Асосийси, бот терминалга эмас, тизимга боғланган бўлиши керак.