دیپلوی Next.js روی هاست ایرانی بدون وابستگی به Vercel
خیلی از پروژههای Next.js ناخواسته به قابلیتهای اختصاصی Vercel گره میخورند و بعد روی سرور معمولی کار نمیکنند. چهار تصمیمی که این را از ابتدا حل میکند.
Next.js یک فریمورک متنباز است و هیچ الزامی به میزبانی روی Vercel ندارد. ولی چند قابلیت وجود دارد که اگر استفادهشان کنید، پروژه عملاً فقط آنجا اجرا میشود — و معمولاً وقتی متوجه میشوید که دیر است.
این چهار تصمیم را از روز اول بگیرید.
۱. output: "standalone"
بدون این، خروجی بیلد به کل node_modules وابسته است و برای اجرا باید همه چیز را روی سرور ببرید.
// next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "standalone",
poweredByHeader: false,
compress: true,
};
export default nextConfig;خروجی در .next/standalone یک سرور Node مستقل است که با node server.js بالا میآید. دو نکته که معمولاً فراموش میشود:
# پوشههای استاتیک بهصورت خودکار کپی نمیشوند.
cp -r public .next/standalone/public
cp -r .next/static .next/standalone/.next/static۲. هیچ runtime = "edge"
Edge Runtime یک محیط V8 محدود است، نه Node. روی سرور معمولی، روتهایی که این را اعلام کردهاند یا کار نمیکنند یا رفتار متفاوتی دارند. برای پروژهای که قرار است روی Node اجرا شود، سود این قابلیت صفر است و هزینهاش قفلشدن.
// در route handlerها صراحتاً Node را اعلام کنید
export const runtime = "nodejs";۳. بهینهسازی تصویر در زمان بیلد
next/image با لودر پیشفرض روی سرور خودتان هم کار میکند، ولی تصاویر را در اولین درخواست تغییر اندازه میدهد و در .next/cache/images مینویسد. روی هاست اشتراکی این یعنی اولین بازدید هر تصویر کند است، و اگر فایلسیستم محدود باشد اصلاً شکست میخورد.
راه پایدارتر: تصاویر را در زمان بیلد بسازید.
// next.config.mjs
images: { unoptimized: true },و یک اسکریپت بیلد که با sharp نسخههای AVIF و WebP را در چند عرض تولید کند. نتیجه: صفر CPU در زمان اجرا و رفتار یکسان روی هر هاستی.
۴. متغیرهای محیطی از فایل
هر چیزی که در زمان بیلد خوانده میشود (NEXT_PUBLIC_*) باید موقع بیلد موجود باشد. اگر روی سرور بیلد میگیرید، یک .env.production کنار پروژه؛ اگر بیلد در CI انجام میشود، متغیرها باید همانجا تعریف شوند.
اجرا روی سرور
با PM2:
cd .next/standalone
pm2 start server.js --name site --env production -i 1
pm2 saveتوجه کنید به -i 1. اگر از حالت cluster استفاده کنید، هر پروسه حافظه خودش را دارد — یعنی هر ریتلیمیت یا کش درونحافظهای که نوشتهاید، به تعداد پروسهها ضرب میشود.
روی cPanel با Node.js Selector، فایل شروع را .next/standalone/server.js بگذارید و NODE_ENV=production و PORT را در همان پنل تعریف کنید.
چکلیست قبل از تحویل
npm run buildروی همان نسخه Node سرور تست شده باشد.- پوشههای
publicو.next/staticکپی شده باشند. NEXT_PUBLIC_SITE_URLمقدار درست داشته باشد.- هدرهای کش برای
/_next/staticروی immutable تنظیم شده باشد. - یک ریستارت کامل سرور را تست کنید، نه فقط اولین اجرا.