Botni serverga joylash
Bot noutbukda ishlayapti, lekin qopqoqni yopsangiz u ham uxlaydi. Bu bobda kodni doimiy yoqiq turadigan serverga ko'chiramiz: SSH, systemd, Docker, Nginx va HTTPS.
Bu bob asl darslikka qo'shimcha sifatida onlayn nashr uchun yozilgan.
Oldingi boblarda kompyuter ichida nima bo'lishini o'rgandik. Endi amaliy savol: yozgan botingiz qayerda ishlashi kerak? Uni node bot.js bilan noutbukda ishga tushirish oson, lekin bu vaqtinchalik yechim. Bu bobda botni haqiqiy serverga joylash yo'lini boshidan oxirigacha ko'ramiz.
15.1. Server qayerda turadi
1.3-bo'limda aytganimizdek, server — doimiy yoqiq turadigan oddiy kompyuter. Bunday kompyuterlar data-markazlarda turadi: minglab server javonlarga terilgan, ularga ikki tomonlama elektr, sovutish va tezkor internet ulangan bino. Butun bir serverni ijaraga olish mumkin (alohida server, dedicated) — bu qimmat. Ko'pincha VPS olinadi: bitta kuchli server virtual mashinalarga bo'linadi va har biriga alohida foydalanuvchi joylashtiriladi. Odatiy VPS — 1–2 yadro, 1–2 GB RAM, 20–40 GB SSD — Telegram bot uchun bemalol yetadi va oyiga bir necha dollar turadi. Uchinchi yo'l — "serverless": siz faqat funksiya yozasiz, uni qachon va qaysi mashinada ishga tushirishni provayder hal qiladi; kam so'rovda arzon, lekin nazorat kam.
Nega noutbukdan ishlatib bo'lmaydi? Uchta sabab. Birinchi, noutbuk uxlaydi: qopqoq yopildi — jarayon to'xtadi. Ikkinchi, uy internetining IP manzili vaqti-vaqti bilan o'zgaradi, Telegram esa webhook uchun doimiy manzil kutadi. Uchinchi, uy routeri NAT ortida: butun uy bitta tashqi IP bilan chiqadi va tashqaridan sizning kompyuteringizga ulanib bo'lmaydi. 13.4-bo'limdagi mijoz-server modeli esa doimiy ochiq IP va 24 soat kutib turadigan dasturni talab qiladi.
15.2. SSH va Linux terminali
Serverga ekran va klaviatura ulanmagan. Unga tarmoq orqali SSH bilan kiriladi: ssh muhammad@185.199.108.153. SSH — shifrlangan terminal: siz yozgan har bir buyruq va uning natijasi 13.3-bo'limdagi kabi shifrlangan tunnel orqali o'tadi. Parol o'rniga kalit juftligi ishlatish xavfsizroq: yopiq kalit sizning kompyuteringizda qoladi, ochiq kalit esa serverdagi ~/.ssh/authorized_keys fayliga yoziladi. Kirishda server tasodifiy son yuboradi, siz uni yopiq kalit bilan imzolaysiz, server imzoni ochiq kalit bilan tekshiradi — maxfiy narsa tarmoqdan umuman o'tmaydi.
Kirganingizdan keyin bir necha buyruq yetadi: ls (fayllar ro'yxati), cd (papkaga o'tish), nano bot.js (oddiy muharrir), htop (jarayonlar, CPU va RAM jonli), df -h (disk qancha to'lgan), free -m (megabaytlarda bo'sh xotira). root hamma narsani qila oladi, shuning uchun kundalik ish oddiy foydalanuvchidan qilinadi, kerak bo'lganda sudo bilan bitta buyruqqa vaqtincha to'liq huquq olinadi. Firewall faqat kerakli portlarni ochadi, qolgani yopiq:
sudo ufw allow OpenSSH # 22-port; buni unutsangiz, o'zingiz ham kirolmaysiz
sudo ufw allow 443/tcp # HTTPS — Telegram webhook shu portga keladi
sudo ufw enable
PostgreSQL'ning 5432-porti ochilmaydi: baza faqat shu serverning ichidan, localhost orqali so'rov oladi.
15.3. Dastur doimiy ishlashi kerak
SSH orqali node bot.js deb yozsangiz, bot ishlaydi — terminalni yopguningizcha. 11.3-bo'limdagi jarayon o'zini ishga tushirgan terminalga bog'langan: terminal yopilganda OS unga SIGHUP signalini yuboradi va jarayon tugaydi. Serverda dastur nazoratchi ostida ishlashi kerak. Linux'da bu systemd — yuklanishda birinchi bo'lib ishga tushadigan jarayon (11.1). Unga kichik "unit" fayl yoziladi:
# /etc/systemd/system/bot.service
[Unit]
Description=Telegram bot
After=network-online.target
[Service]
User=muhammad
WorkingDirectory=/home/muhammad/bot
EnvironmentFile=/home/muhammad/bot/.env
ExecStart=/usr/bin/node bot.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
# sudo systemctl enable --now bot # hozir ham, qayta yuklanganda ham
# journalctl -u bot -f # loglarni jonli ko'rish
Restart=always degani: bot xato bilan tugasa, systemd uni 5 soniyadan keyin qayta ishga tushiradi; server qayta yuklansa ham bot avtomatik ko'tariladi. Loglar journalctl -u bot -f bilan o'qiladi. Node.js olamida shu ishni PM2 ham qiladi:
npm install -g pm2
pm2 start bot.js --name bot # ishga tushirish va kuzatish
pm2 logs bot # loglar
pm2 startup && pm2 save # server qayta yuklanganda ham ko'tarilsin
Tokenni kodga yozmang: bot.js GitHub'ga tushadi va tokenni bir soat ichida birov topadi. Token muhit o'zgaruvchisida saqlanadi: serverda .env fayl (BOT_TOKEN=123456:ABC...) yaratiladi, systemd uni EnvironmentFile orqali o'qiydi, kodda esa process.env.BOT_TOKEN yoziladi. .env .gitignore'ga kiritiladi.
15.4. Docker: "menda ishlaydi" muammosi
Klassik muammo: "menda ishlaydi, serverda ishlamaydi". Noutbukda Node 22, serverda 18; bir kutubxonaning versiyasi boshqa. Docker bu muammoni dastur bilan birga uning butun muhitini "qadoqlash" orqali hal qiladi. Image — bu qolip: fayl tizimining muzlatilgan nusxasi, u qatlamlarga bo'lingan. Asosda kichik Linux (Alpine, atigi 5 MB), ustida Node.js, ustida npm paketlar, eng tepada sizning kod. 12-rasmdagi abstraksiya qatlamlari kabi har qatlam pastdagisiga tayanadi; kodni o'zgartirsangiz, faqat eng yuqori qatlam qayta quriladi. Container — shu qolipdan ishga tushirilgan jarayon; bitta image'dan istalgancha konteyner ochish mumkin. Image Dockerfile bilan tasvirlanadi:
FROM node:22-alpine # asos qatlam: Alpine Linux + Node.js 22
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev # paketlar qatlami (package.json o'zgarmasa keshdan)
COPY . . # sizning kod — eng yuqori qatlam
ENV NODE_ENV=production
CMD ["node", "bot.js"]
Konteyner virtual mashina emas. VM o'z yadrosi bilan butun OS'ni yuklaydi — bu gigabaytlar va daqiqalar. Konteyner esa serverning Linux yadrosidan foydalanadi, faqat fayllar, jarayonlar va tarmoq izolyatsiya qilingan — megabaytlar va soniyalar. Bot va baza birga docker compose bilan tasvirlanadi: compose.yaml faylida ikkita xizmat — bot (o'z Dockerfile'idan quriladi) va postgres (tayyor image); docker compose up -d bilan ikkisi ham ko'tariladi, bazaning fayllari esa volume'da saqlanadi — konteyner o'chsa ham ma'lumot qoladi.
15.5. Domen, Nginx va HTTPS
Telegram webhook'i faqat HTTPS manzilga yuboriladi. Sababi 13.3-bo'limda: Telegram sizning serveringiz haqiqiy ekanini sertifikat orqali tekshiradi, yo'ldagi routerlar esa foydalanuvchi xabarlarini o'qiy olmaydi. Sertifikat IP'ga emas, domenga beriladi. Shuning uchun avval domen olinadi va DNS'da A-yozuv (13.2) serveringiz IP'siga yo'naltiriladi: bot.misol.uz → 185.199.108.153.
Node.js dasturi to'g'ridan-to'g'ri 443-portni tinglashi shart emas. Oldida Nginx turadi — reverse proxy: u 443-portda TLS'ni yechadi va so'rovni oddiy HTTP sifatida localhost:3000 ga uzatadi. Sertifikat bir joyda turadi, Node.js esa root huquqisiz, oddiy portda ishlaydi.
# /etc/nginx/sites-available/bot
server {
listen 443 ssl;
server_name bot.misol.uz;
ssl_certificate /etc/letsencrypt/live/bot.misol.uz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bot.misol.uz/privkey.pem;
location /webhook {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
}
}
Sertifikat Let's Encrypt'dan bepul olinadi: sudo certbot --nginx -d bot.misol.uz. Certbot domen sizniki ekanini tekshiradi, sertifikatni Nginx sozlamasiga o'zi qo'shadi va har 90 kunda yangilab turadi. Oxirgi qadam — Telegram'ga botning manzilini aytish:
curl -F "url=https://bot.misol.uz/webhook" \
https://api.telegram.org/bot<TOKEN>/setWebhook
Shundan keyin har bir xabar 30-rasmdagi yo'l bilan serveringizga POST so'rov sifatida keladi. Nimadir ishlamasa, getWebhookInfo Telegram ko'rgan oxirgi xatoni ko'rsatadi.
15.6. Kuzatuv va xatolarni topish
Server ishga tushdi — endi uni kuzatish kerak. Uchta resurs muhim. CPU: htop'da 100% uzoq tursa, qayerdadir cheksiz sikl bor; bitta oqimli Node.js'da bu butun botni to'xtatadi. RAM: botning xotirasi kundan-kunga o'sib borsa, bu xotira oqishi (12.3): obyektlarga havola qolgani uchun axlat yig'uvchi ularni bo'shata olmaydi; 1 GB to'lganda OS jarayonni o'ldiradi (OOM), nazoratchi uni qayta ko'taradi va sikl takrorlanadi. Disk: eng ko'p uchraydigan halokat — loglar diskni to'ldiradi va bot bazaga ham, logga ham yoza olmaydi (ENOSPC xatosi). Log aylantirish (logrotate, pm2-logrotate) eski fayllarni siqib, ma'lum hajmdan keyin o'chirib turadi.
Bot javob bermay qolganda oddiy tekshiruv ro'yxati yordam beradi:
systemctl status botyokipm2 status— jarayon umuman ishlayaptimi?journalctl -u bot -n 50yokipm2 logs bot— oxirgi 50 qator nima deyapti?df -hvafree -m— disk yoki xotira to'lib qolmadimi?curl https://bot.misol.uz/health— Nginx va sertifikat tirikmi?getWebhookInfo— Telegram nima deb shikoyat qilyapti?
Healthcheck — botdagi kichik /health manzili, u shunchaki 200 OK qaytaradi. Tashqi kuzatuv xizmati uni har daqiqa so'rab turadi va javob kelmasa sizga xabar yuboradi. Va nihoyat, zaxira nusxa: pg_dump har kuni bazani faylga saqlaydi, fayl boshqa serverga ko'chiriladi. Server bir soatda qayta quriladi; foydalanuvchilar bazasi esa qaytmaydi.
ufw (22, 443) + systemd yoki PM2 + .env'dagi token + Nginx + certbot + setWebhook + kunlik pg_dump. Docker shart emas, lekin "menda ishlaydi" muammosi boshlansa, yechim aynan u. Har o'zgarishdan keyin journalctl -u bot -f ni ochib qo'ying.