آموزش استقرار Next.js روی Vercel؛ از Preview تا دامنه و Rollback
راهنمای عملی انتشار امن پروژه Next.js روی Vercel؛ از اتصال Git و ساخت Preview تا مدیریت متغیرهای محیطی، دامنه اختصاصی، کنترل کیفیت و بازگشت سریع نسخه خراب.
انتشار یک پروژه Next.js فقط انتقال فایلها به اینترنت نیست. نسخهای که روی لپتاپ درست کار میکند ممکن است بهدلیل متغیر محیطی ناقص، تفاوت Runtime، تنظیم اشتباه دامنه یا Cache در Production شکست بخورد. Vercel راهاندازی را ساده میکند، اما یک انتشار حرفهای هنوز به مرزبندی محیطها، تست Preview، کنترل Secret و برنامه بازگشت نیاز دارد.
در این راهنما یک پروژه Next.js را از Repository تا دامنه اختصاصی منتشر میکنیم. هدف این است که هر Pull Request یک Preview قابلآزمایش داشته باشد، فقط نسخه تأییدشده وارد Production شود و در صورت خطا بتوانیم بدون تصمیمگیری عجولانه سرویس را به نسخه سالم برگردانیم.
Vercel چیست و کجای معماری قرار میگیرد؟
Vercel یک پلتفرم استقرار و اجرای برنامههای وب است که با Next.js یکپارچگی عمیقی دارد. هر Deployment خروجی یک Build مشخص است و URL جداگانه دریافت میکند. اتصال Repository باعث میشود Push روی Branchها Preview بسازد و تغییرات Production Branch معمولاً به انتشار Production منتهی شود.
این سه مفهوم را از هم جدا نگه دارید: Git منبع تغییرات است، Vercel Build و Runtime را اجرا میکند و سرویسهایی مانند Database یا Object Storage مستقلاند. Rollback رابط وب، Schema دیتابیس را عقب نمیبرد؛ بنابراین Migration سازگار با نسخه قبل بخشی از طراحی انتشار است.
| محیط | کاربرد | داده و Secret پیشنهادی | شرط عبور |
|---|---|---|---|
| Development | توسعه محلی | داده آزمایشی محلی | Lint، Type Check و Test |
| Preview | بازبینی Branch یا PR | سرویس آزمایشی جدا | Smoke Test و تأیید تیم |
| Production | ترافیک واقعی | Secret و داده Production | Merge کنترلشده و مانیتورینگ |
پیشنیازهای انتشار
- پروژه Next.js که Build محلی آن موفق است
- Repository روی GitHub، GitLab، Bitbucket یا Azure DevOps
- حساب Vercel و دسترسی به تنظیمات Project
- فهرست متغیرهای محیطی بدون مقدار Secret در مستندات تیم
- دامنه اختیاری و دسترسی به DNS Provider
- یک سناریوی Smoke Test برای صفحه اصلی، ورود، API و مسیر خطا
قبل از اتصال سرویس، Build واقعی را محلی اجرا کنید. این مرحله خطاهای TypeScript، Import حساس به حروف بزرگ و وابستگیهای ثبتنشده را زودتر آشکار میکند.
npm cinpm run lintnpm run testnpm run buildnpm run startفرمان npm ci از Lockfile استفاده میکند و برای CI قابلپیشبینیتر است. اجرای next start پس از Build کمک میکند رفتار Production را پیش از Push ببینید.
اتصال Git و ساخت نخستین Preview
در Dashboard یک Project تازه بسازید و Repository را Import کنید. Vercel معمولاً Framework را تشخیص میدهد، اما Root Directory، Package Manager و Build Command را بررسی کنید؛ در Monorepo انتخاب اشتباه Root باعث Build شدن Package دیگری میشود.
- Repository و Branch اصلی را انتخاب کنید.
- Framework Preset را روی Next.js نگه دارید.
- Root Directory را با محل
package.jsonتطبیق دهید. - متغیرهای لازم برای Preview را وارد کنید.
- Deployment اول را بسازید و Log کامل Build را بررسی کنید.
چرا Preview باید داده جدا داشته باشد؟
Preview عمومی یا قابلاشتراک است و کد یک Branch آزمایشی را اجرا میکند. اتصال آن به Database واقعی میتواند تست را به تغییر داده کاربران تبدیل کند. برای Preview از Project یا Schema جدا، حسابهای Test و Scope محدود استفاده کنید. هر Secret فقط در محیطی قرار بگیرد که واقعاً به آن نیاز دارد.
پس از ایجاد PR، URL اختصاصی Preview را باز کنید و فقط ظاهر صفحه اصلی را نبینید. Login، مجوزها، ارسال Form، Route Handler، فایلهای Static، تصویر و صفحه 404 را هم آزمایش کنید.
مدیریت درست Environment Variableها
Vercel متغیرها را برای Development، Preview و Production جدا میکند. تغییر یک Variable روی Deploymentهای قبلی اعمال نمیشود و برای دریافت مقدار جدید باید Deployment تازه ساخته شود. نامها را یکسان و مقدارها را متناسب با محیط نگه دارید.
NEXT_PUBLIC_APP_URL=https://preview.example.testDATABASE_URL=postgresql://user:password@host/databaseAUTH_SECRET=replace-with-a-random-secretSTORAGE_BUCKET=project-previewفایل مثال فقط نام و شکل Variableها را نشان میدهد؛ مقدار واقعی را Commit نکنید. پیشوند NEXT_PUBLIC_ یعنی مقدار در Bundle مرورگر قابلمشاهده است، پس Token، Password و Connection String هرگز نباید این پیشوند را داشته باشند.
اعتبارسنجی Variableها هنگام شروع
بهتر است برنامه بهجای شکست مبهم در نخستین درخواست، در Build یا Startup نبودن Variable لازم را اعلام کند. یک ماژول Server-only برای خواندن مقادیر بسازید و فقط خروجیهای عمومی را جداگانه صادر کنید.
import 'server-only' function required(name: string) { const value = process.env[name] if (!value) throw new Error('Missing environment variable: ' + name) return value} export const env = { databaseUrl: required('DATABASE_URL'), authSecret: required('AUTH_SECRET')}پیام خطا فقط نام Variable را نشان میدهد و مقدار Secret را Log نمیکند. در Log، Error Tracker و پاسخ API نیز Token و Connection String را Redact کنید.
Deployment با Git یا CLI
جریان Git برای بیشتر تیمها ساده است: Push روی Branch یک Preview میسازد و Merge در Production Branch انتشار نهایی را آغاز میکند. CLI برای آزمایش محلی، CI سفارشی یا انتشار کنترلشده مناسب است.
pnpm i -g vercelvercel linkvercel env pull .env.localvercel deployvercel logs --deployment PREVIEW_DEPLOYMENT_ID --level errorvercel deploy --prodفرمان Preview بدون --prod اجرا میشود. شناسه یا URL خروجی را در فرایند QA ثبت کنید. Secret را داخل Command History یا آرگومان خط فرمان قرار ندهید؛ از مدیریت Variable خود Vercel یا Secret Store در CI استفاده کنید.
اضافهکردن دامنه اختصاصی
هر Deployment یک URL با دامنه vercel.app دارد. برای سایت واقعی، دامنه را از Project Settings و بخش Domains اضافه کنید. Vercel Record لازم را نشان میدهد؛ همان Record را در DNS Provider ایجاد کنید و Recordهای متعارض قدیمی را پس از بررسی حذف یا اصلاح کنید.
- Apex Domain و نسخه
wwwرا به Project اضافه کنید. - Canonical اصلی را انتخاب و Redirect نسخه دوم را مشخص کنید.
- DNS Record پیشنهادی Dashboard را دقیق اعمال کنید.
- منتظر Propagation بمانید و وضعیت Verification را بررسی کنید.
- HTTPS، Redirect، Cookie Domain و Callback URL احراز هویت را تست کنید.
اگر Nameserver دامنه را جابهجا میکنید، Recordهای Email مانند MX، SPF، DKIM و DMARC را از قلم نیندازید. هدف انتشار وبسایت نباید باعث قطع سرویس ایمیل شود.
چکلیست Preview پیش از Production
| آزمون | روش | نشانه قبولی |
|---|---|---|
| Build | Log و Warningها | بدون Error و Secret چاپشده |
| Routing | صفحه اصلی، Dynamic Route و 404 | Status و محتوا صحیح |
| Auth | Login، Logout و Callback | Cookie امن و Redirect درست |
| API | درخواست مجاز و غیرمجاز | Validation و Status مناسب |
| SEO | Title، Canonical و robots | Preview ایندکس نشود |
| Performance | Lighthouse و Log زمان پاسخ | افت غیرعادی وجود ندارد |
| Data | تراکنش آزمایشی | به Production متصل نیست |
Preview را با حساب ناشناس و حساب واردشده بررسی کنید. لینک Preview را در PR ثبت کنید تا Review کد و Review رفتار یک مرجع مشترک داشته باشند.
انتشار Production با امکان بازگشت
پیش از Merge، Deployment سالم قبلی، Migrationهای جدید و مالک تصمیم Rollback را مشخص کنید. اگر Migration ستون را حذف کند اما نسخه قبلی هنوز به آن نیاز داشته باشد، بازگرداندن Frontend کافی نیست. الگوی امنتر Expand و Contract است: ابتدا تغییر سازگار اضافه شود، کد جدید منتشر شود و حذف قدیمی در انتشار بعدی انجام گیرد.
چه چیزی را بعد از انتشار فوراً بسنجیم؟
- نرخ خطای Server Function و Route Handler
- زمان پاسخ و Core Web Vitals
- خطاهای ورود و Callback
- اتصال Database و محدودیت Connection
- صفحات کلیدی و عملیات تبدیل
- وضعیت دامنه، Redirect و گواهی HTTPS
تأیید Deployment با موفقیت Build تمام نمیشود. Smoke Test را روی دامنه اصلی اجرا و زمان شروع مشاهده را ثبت کنید. اگر Error Rate یا رفتار دادهای غیرعادی است، بین Rollback، خاموشکردن Feature Flag و Hotfix براساس Runbook تصمیم بگیرید.
Rollback در Vercel چگونه کار میکند؟
Instant Rollback ترافیک دامنه Production را به Deployment قبلی واجدشرایط برمیگرداند و Build جدیدی انجام نمیدهد. به همین دلیل سریع است، اما Environment Variableهای تازه را دوباره Build نمیکند و سرویسهای بیرونی یا Database را به عقب نمیبرد.
| وضعیت | اقدام مناسب | ریسک اصلی |
|---|---|---|
| خرابی واضح رابط یا Runtime | Instant Rollback | ناسازگاری با Database جدید |
| اشکال کوچک و بدون اثر داده | Hotfix و Deployment تازه | طولانیشدن Incident |
| Feature جدید مشکلدار | Feature Flag Off | پوشش ناقص Flag |
| Secret لو رفته | Rotate و Redeploy | Rollback Secret را باطل نمیکند |
پس از Rollback، علت رخداد را رفع و Deployment اصلاحشده را Promote کنید. طبق مستندات Vercel، Rollback میتواند Auto-assignment دامنه Production را متوقف کند؛ پس بازگشت به جریان عادی را نیز در Runbook قرار دهید.
خطاهای رایج و راهحل
Variable در Production مقدار undefined دارد
مطمئن شوید Variable برای Environment درست تعریف شده و پس از تغییر، Deployment جدید ساختهاید. تفاوت حروف بزرگ و کوچک نام را بررسی کنید و مقدار Secret را در Log چاپ نکنید.
Build محلی موفق و Vercel ناموفق است
نسخه Node، Lockfile، Root Directory، Scriptهای package.json و حساسیت مسیرها به حروف را بررسی کنید. Packageهایی که فقط بهصورت سراسری نصب شدهاند باید در Dependency پروژه ثبت شوند.
دامنه باز میشود اما Login برنمیگردد
Callback URL سرویس Auth، متغیر Base URL، Cookie Domain و پروتکل HTTPS را کنترل کنید. دامنه Preview و Production را بدون Scope جدا در Allowlist رها نکنید.
نسخه جدید داده قدیمی نشان میدهد
رفتار Cache و Revalidation را مشخص کنید. تفاوت Cache مرورگر، CDN، Data Cache و خروجی Static را تشخیص دهید؛ افزودن تصادفی no-store به همه درخواستها راهحل عمومی نیست.
چکلیست نهایی انتشار
- Build محلی و Preview هر دو موفقاند.
- Secretها فقط در Scope لازم قرار دارند.
- Preview به داده Production متصل نیست.
- صفحات خطا و Routeهای محافظتشده تست شدهاند.
- Canonical و robots محیطها صحیحاند.
- دامنه، HTTPS و Redirect بررسی شدهاند.
- Migration با نسخه قبلی سازگار است.
- Deployment سالم قبلی و روش Rollback مشخص است.
- مالک مانیتورینگ پس از انتشار تعیین شده است.
- Logها هیچ Token یا داده شخصی آشکار ندارند.
مسیرهای مکمل یادگیری
اگر Backend پروژه را با سرویس آماده میسازید، آموزش Supabase و Next.js مرز امنیت Database را توضیح میدهد. برای ساخت سایت محتوایی، راهنمای Headless WordPress با Next.js مفید است. اگر استقرار Containerمحور میخواهید، راهنمای نصب امن با Docker Compose نگاه عملی دیگری ارائه میکند.
جمعبندی
Vercel انتشار Next.js را سریع میکند، اما سرعت بدون کنترل محیط و مسیر بازگشت کافی نیست. Git Branch باید Preview مستقل بسازد، Variableها براساس Environment جدا شوند و Production فقط پس از Smoke Test و Review منتشر شود.
دامنه اختصاصی، HTTPS و Build سبز پایان کار نیستند. رفتار Auth، API، Cache، داده و مانیتورینگ را روی دامنه واقعی بررسی کنید. Rollback را پیش از Incident بشناسید و Migrationها را طوری طراحی کنید که نسخه سالم قبلی هنوز قابل اجرا باشد.
امروز یک Branch آزمایشی بساز، Preview آن را منتشر کن و پیش از Merge، چکلیست Smoke Test و Deployment سالم مقصد Rollback را ثبت کن.