Оддий усулда жойланган Next.js лойиҳаси серверда бутун node_modules папкасини талаб қилади. Бу папкада build учун керак бўлган, лекин ишлаш вақтида ҳеч қачон ишлатилмайдиган юзлаб пакетлар бор: TypeScript, линтерлар, тест кутубхоналари ва бошқалар. Кичик VPS'да бу диск жойини эгаллайди, деплой вақтини узайтиради ва Docker image'ларини оғирлаштиради. Next.js'нинг standalone режими айнан шу муаммони ҳал қилади: build вақтида у илова ҳақиқатан ишлатадиган файлларни кузатиб, уларни алоҳида папкага йиғади.
Standalone режим қандай ишлайди
Build пайтида Next.js ҳар бир саҳифа ва API route қайси модулларни импорт қилишини таҳлил қилади. Standalone ёқилган бўлса, натижада .next/standalone папкаси пайдо бўлади. Унинг ичида минимал server.js файли ва фақат зарур пакетлардан иборат қисқартирилган node_modules бўлади. Бу папка next start буйруғига муҳтож эмас, у оддий node server.js билан ишга тушади. Шу сабабли серверга бутун лойиҳани эмас, фақат шу папкани кўчириш кифоя.
Standalone'ни ёқиш
Созлаш битта қатордан иборат. Лойиҳанинг next.config.js ёки next.config.mjs файлига output параметрини қўшинг ва build'ни қайта бажаринг.
// next.config.mjs
const nextConfig = {
output: "standalone",
};
export default nextConfig;
npm ci
npm run build
ls .next/standalone
Build тугагач, .next/standalone папкасида server.js, package.json, node_modules ва .next ички папкасини кўрасиз. Ҳажмни солиштириш учун du -sh node_modules .next/standalone буйруғини бажариб кўринг, фарқ лойиҳага қараб ҳар хил бўлади, лекин одатда сезиларли.
Энг кўп унутиладиган қадам: public ва static
Standalone папкасига икки нарса автоматик қўшилмайди: public папкаси ва .next/static ичидаги CSS, JavaScript бўлаклари. Next.js бу файлларни атайлаб ташлаб кетади, чунки уларни Nginx ёки CDN орқали тўғридан-тўғри бериш самаралироқ деб ҳисоблайди. Агар уларни кўчирмасангиз, сайт очилади, лекин дизайнсиз, расмларсиз ва тугмалар ишламайдиган ҳолда бўлади. Кўпчилик биринчи марта айнан шу ерда адашади.
cp -r public .next/standalone/
cp -r .next/static .next/standalone/.next/
Бу икки буйруқни build скриптига қўшиб қўйиш яхши одат, шунда кейинги деплойларда улар унутилмайди. package.json да шундай ёзиш мумкин.
"scripts": {
"build": "next build",
"postbuild": "cp -r public .next/standalone/ && cp -r .next/static .next/standalone/.next/"
}
Серверда ишга тушириш
Standalone сервер порт ва манзилни муҳит ўзгарувчилари орқали олади. PORT қайси портда тинглашни, HOSTNAME эса қайси манзилда тинглашни белгилайди. Nginx орқасида ишлатилганда 127.0.0.1 ни кўрсатиш хавфсизроқ, Docker ичида эса 0.0.0.0 керак бўлади.
cd /var/www/misol-next/.next/standalone
PORT=3000 HOSTNAME=127.0.0.1 NODE_ENV=production node server.js
Доимий ишлаши учун PM2 ecosystem файли қулай. У иловани фонда ушлайди, йиқилса қайта кўтаради ва хотира чегарасидан ошса қайта ишга туширади.
// ecosystem.config.js
module.exports = {
apps: [{
name: "misol-next",
cwd: "/var/www/misol-next/.next/standalone",
script: "server.js",
max_memory_restart: "400M",
env: { NODE_ENV: "production", PORT: 3000, HOSTNAME: "127.0.0.1" }
}]
};
Build'ни сервердан ташқарида қилиш
Standalone режимнинг энг катта афзаллиги шундаки, build'ни кучли компьютерда ёки CI'да бажариб, серверга тайёр папкани юбориш мумкин. Кичик VPS build пайтида хотира етишмаслигидан қийналмайди, сервер фақат тайёр иловани ишлатади. Муҳим шарт битта: build қилинадиган машинанинг операцион тизими ва процессор архитектураси сервер билан мос бўлиши керак, чунки баъзи пакетларда, масалан расмларни қайта ишловчи sharp'да, платформага боғлиқ бинар файллар бор.
npm run build
tar -czf release.tar.gz -C .next/standalone .
scp release.tar.gz deploy@example.uz:/var/www/misol-next/releases/
Docker билан ишлатиш
Docker'да standalone айниқса фойдали, чунки якуний image'да фақат ишлаш учун керакли файллар қолади. Қуйида кўп босқичли Dockerfile'нинг соддалаштирилган варианти келтирилган. Биринчи босқичда build бажарилади, иккинчисида эса фақат натижа кўчирилади.
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
ENV NODE_ENV=production PORT=3000 HOSTNAME=0.0.0.0
COPY --from=build /app/.next/standalone ./
COPY --from=build /app/.next/static ./.next/static
COPY --from=build /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]
Амалий мисол: Намангандаги мебель дўкони
Намангандаги мебель дўкони каталог сайтини Next.js'да ишлатади ва уни 1 GB хотирали кичик VPS'да ушлайди. Аввал build тўғридан-тўғри серверда бажариларди ва ҳар сафар хотира тугаб, сайт бир неча дақиқа ишламай қоларди. Standalone режимга ўтгандан кейин build дастурчининг компьютерида бажарилади, серверга фақат тайёр архив юборилади ва PM2 иловани қайта юклайди. Серверда энди бутун node_modules ўрнига фақат керакли пакетлар туради, деплой эса бир дақиқадан камроқ вақт олади.
Тез-тез учрайдиган муаммолар
- Сайт дизайнсиз очилади:
.next/staticкўчирилмаган. - Расмлар ва favicon 404 беради:
publicпапкаси кўчирилмаган. - Docker'да сайт ташқаридан очилмайди:
HOSTNAME=0.0.0.0берилмаган. - Муҳит ўзгарувчилари ишламайди:
.envфайллари standalone папкасига автоматик тушмайди, уларни серверда алоҳида беринг.
Кам ресурсли серверда Next.js ишлатмоқчи бўлсангиз, sayt.uz кабинетидан кичик VPS олиб, standalone режим билан бошлаш яхши вариант. Ресурс етмай қолса, тарифни кейинчалик катталаштириш мумкин.