NestJS lokal kompyuterda npm run start:dev bilan juda qulay ishlaydi: kod o'zgarsa server o'zi qayta ishga tushadi, xatolar darhol terminalda ko'rinadi. Lekin production muhiti boshqa talablar qo'yadi. U yerda ilova kechayu kunduz to'xtamasdan ishlashi, server qayta yuklanganda o'zi ko'tarilishi, maxfiy kalitlarni koddan alohida saqlashi va tashqi dunyo bilan faqat himoyalangan HTTPS orqali gaplashishi kerak. Ushbu maqolada Toshkentdagi kichik yetkazib berish xizmati uchun yozilgan API misolida NestJS ilovasini VPS serverga bosqichma-bosqich chiqaramiz.
Qaysi server kerak: VPS yoki oddiy hosting
NestJS doimiy ishlab turadigan Node.js jarayoni hisoblanadi, ya'ni u PHP saytlar kabi har so'rovda ishga tushib, keyin o'chib qolmaydi. Shu sababli unga o'z portini tinglab turadigan va fon jarayonlarni ushlab tura oladigan muhit kerak. Eng ishonchli variant bu VPS: unda Node.js versiyasini o'zingiz tanlaysiz, PM2 yoki systemd o'rnatasiz va Nginx'ni xohlagancha sozlaysiz. Oddiy shared hostingda Node.js ilovalarini ishlatish imkoniyati tarif va panel sozlamalariga bog'liq, shuning uchun loyihani boshlashdan oldin buni sayt.uz kabinetidan yoki texnik yordam orqali aniqlab olish foydali.
Bizning misolimizda api.example.uz manzilida ishlaydigan buyurtmalar API'si bor. U PostgreSQL bazasidan foydalanadi, kuryerlarga Telegram orqali xabar yuboradi va mobil ilova bilan JSON orqali gaplashadi. Server sifatida Ubuntu o'rnatilgan VPS olingan, domenning A yozuvi esa shu serverning IP manziliga yo'naltirilgan.
Kodni production uchun tayyorlash
Birinchi navbatda main.ts faylini ko'rib chiqing. Ilova portni muhit o'zgaruvchisidan olishi, faqat ichki interfeysni tinglashi va to'xtash signallarini to'g'ri qayta ishlashi kerak. enableShutdownHooks() chaqiruvi PM2 yoki systemd jarayonni to'xtatganda bazaga ulanishlarni toza yopishga imkon beradi. Nginx orqasida ishlaganda mijozning haqiqiy IP manzilini ko'rish uchun Express'ning trust proxy sozlamasini yoqish ham muhim.
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.set('trust proxy', 1);
app.enableShutdownHooks();
const port = Number(process.env.PORT ?? 3000);
await app.listen(port, '127.0.0.1');
}
bootstrap();
Maxfiy ma'lumotlar, masalan baza paroli, JWT kaliti va Telegram bot tokeni, hech qachon kod ichida yoki Git omborida saqlanmasligi kerak. Ularni serverdagi .env fayliga yozib, @nestjs/config moduli orqali o'qish odatiy yo'l. Faylga faqat ilovani ishlatadigan foydalanuvchi o'qish huquqiga ega bo'lishi uchun chmod 600 .env buyrug'ini bajaring.
Serverda build qilish va ishga tushirish
Production'da TypeScript kodi to'g'ridan-to'g'ri ishlatilmaydi. nest build uni dist papkasidagi oddiy JavaScript fayllarga kompilyatsiya qiladi va server aynan shu fayllarni ishga tushiradi. Bog'liqliklarni o'rnatishda npm install o'rniga npm ci ishlatgan ma'qul, chunki u package-lock.json faylidagi aniq versiyalarni o'rnatadi va kutilmagan yangilanishlar sababli ilova buzilib qolmaydi.
cd /var/www/api
git pull
npm ci
npm run build
npm prune --omit=dev
NODE_ENV=production node dist/main.js
Oxirgi buyruq ilova to'g'ri ishga tushishini tekshirish uchun kerak. Agar terminalda xato chiqmasa va curl http://127.0.0.1:3000 javob qaytarsa, keyingi bosqichga o'tish mumkin.
Baza migratsiyalari: synchronize'dan voz keching
TypeORM'dagi synchronize: true sozlamasi ishlab chiqishda qulay, ammo production'da u jadval tuzilmasini o'zi o'zgartirib, ma'lumotlarni yo'qotishga olib kelishi mumkin. Shuning uchun real serverda bu sozlamani o'chirib, o'zgarishlarni migratsiya fayllari orqali qo'llash kerak. Prisma ishlatadigan loyihalarda buning uchun alohida buyruq bor, u faqat hali qo'llanmagan migratsiyalarni bajaradi va yangi migratsiya yaratmaydi.
# Prisma
npx prisma migrate deploy
# TypeORM (data-source fayli dist ichida bo'lsa)
npx typeorm migration:run -d dist/data-source.js
Migratsiyadan oldin bazaning zaxira nusxasini olish odatga aylansin. Yetkazib berish xizmatida buyurtmalar jadvali yo'qolsa, bu faqat texnik muammo emas, balki mijozlar bilan bog'liq jiddiy biznes yo'qotish hamdir.
PM2 bilan doimiy ishlatish
Terminal yopilganda node dist/main.js jarayoni ham to'xtaydi. Uni fon rejimida ushlab turish, xato bilan yiqilganda qayta ko'tarish va server qayta yuklanganda avtomatik ishga tushirish uchun PM2 jarayon menejeridan foydalanamiz. Klaster rejimi esa ilovani bir nechta protsessor yadrosida parallel ishlatib, yuklama ko'p bo'lganda javob tezligini oshiradi.
npm install -g pm2
NODE_ENV=production pm2 start dist/main.js --name api -i 2
pm2 save
pm2 startup systemd
pm2 logs api --lines 50
pm2 startup buyrug'i ekranga bitta sudo buyrug'ini chiqaradi, uni nusxalab bajarish kerak, aks holda server qayta yuklanganda ilova ko'tarilmaydi. Klaster rejimida har bir nusxa alohida xotiraga ega bo'lishini unutmang: agar ilova xotirada sessiya yoki keshni saqlasa, uni Redis kabi umumiy omborga ko'chirish lozim.
Nginx reverse proxy va HTTPS
Ilova faqat 127.0.0.1:3000 manzilini tinglaydi, tashqi so'rovlarni esa Nginx qabul qilib, unga uzatadi. Bu sxema SSL'ni, siqishni, statik fayllarni va so'rovlar hajmi cheklovlarini Nginx zimmasiga yuklaydi, NestJS esa faqat biznes mantiq bilan shug'ullanadi. WebSocket ishlatilsa, Upgrade sarlavhalari albatta uzatilishi kerak.
server {
listen 80;
server_name api.example.uz;
client_max_body_size 10m;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Konfiguratsiyani saqlagach, sudo nginx -t bilan sintaksisni tekshiring va sudo systemctl reload nginx bilan qayta yuklang. So'ng Certbot yordamida Let's Encrypt sertifikatini oling: sudo certbot --nginx -d api.example.uz. Certbot konfiguratsiyaga 443-port blokini o'zi qo'shadi va sertifikatni avtomatik yangilash uchun taymer o'rnatadi.
Ishga tushirishdan keyingi tekshiruvlar
API ochilgach, bir necha narsani albatta tekshirib chiqing. Bu ro'yxat birinchi haftadagi eng ko'p uchraydigan muammolarning oldini oladi:
- Server qayta yuklangandan keyin
pm2 listilovani online holatda ko'rsatadimi. - 3000-port tashqaridan ochiq emasmi: firewall'da faqat 22, 80 va 443 portlarga ruxsat bering.
- Xato loglari diskni to'ldirib yubormasligi uchun
pm2 install pm2-logrotateo'rnatilganmi. - Oddiy
/healthendpointi bormi, u orqali monitoring xizmati API holatini kuzatib boradi.
Yangilanishlarni chiqarish jarayonini ham oldindan kelishib oling. Eng sodda variant: git pull, npm ci, npm run build, migratsiya va pm2 reload api. Klaster rejimida reload buyrug'i nusxalarni birma-bir almashtiradi, shuning uchun foydalanuvchilar yangilanish paytida uzilishni sezmaydi.