کد روی لپتاپ کار میکند، تستها هم سبز هستند. اما تا وقتی پروژه روی یک ماشین در دسترس نباشد، از نظر کاربر وجود ندارد. دیپلوی همان پل بین این دو حالت است و بیشتر وقتها هم دقیقاً همینجا کار خراب میشود: روی سیستم من اجرا میشد، چرا روی سرور نه؟
این مقاله دیپلوی را از تعریف تا عمل پوشش میدهد: اول مشخص میکنیم دیپلوی دقیقاً چیست و چه تفاوتی با انتشار، هاستینگ و CI/CD دارد، بعد پنج روش رایج را با هم مقایسه میکنیم، بعد به آن چیزهایی میرسیم که واقعاً دیپلوی را سالم نگه میدارند: پورت، متغیر محیطی، بررسی سلامت، دیپلوی بدون قطعی و برگشت به عقب.
اگر تازه شروع کردهای، بخش روشها و چکلیست آخر کافی است. اگر قبلاً چند بار دیپلوی کردهای و دنبال خطاهای تکرارشونده هستی، مستقیم برو سر جدول خطاها.
پاسخ کوتاه: دیپلوی چیست؟
- تعریف
- انتقال یک نسخه از پروژه به محیطی که کاربر واقعی میتواند از طریق یک آدرس به آن دسترسی داشته باشد.
- خروجی
- یک آدرس فعال (دامنه یا IP) که سرویس روی آن جواب میدهد.
- حداقل شرط
- build، خروجی/ایمیج مشخص، تنظیم متغیرهای محیطی، اجرای پروسه و یک بررسی سلامت.
- روشها
- دستی (FTP/SSH)، VPS با Docker، پلتفرم PaaS با git push، سایت استاتیک روی CDN، سرورلس.
- زمان
- از چند ثانیه برای سایت استاتیک تا چند دقیقه برای پروژهٔ کانتینری.
- هزینه
- استاتیک تقریباً صفر، PaaS ساعتی و بهازای مصرف، VPS ماهانه با منابع ثابت.
دیپلوی چیست؟
دیپلوی (Deploy) یا استقرار، یعنی نسخهای از نرمافزار را روی محیطی بگذاری که در دسترس کاربر باشد. تا قبل از این مرحله، پروژه فقط روی کامپیوتر خودت اجرا میشود. بعد از آن، یک آدرس وجود دارد که هر کسی با مرورگر یا کلاینت به آن وصل میشود.
یک مثال ساده: کد مثل دستور پخت غذاست و اجرای محلی مثل پختن آن در آشپزخانهٔ خانه. دیپلوی یعنی همان غذا را در رستوران سرو کنی؛ آشپزخانه عوض میشود، ظرفیت عوض میشود و حالا مشتری هم داری.
در عمل، سه چیز تغییر میکند و همین سه چیز منبع بیشتر خطاهاست:
- آدرس: سرویس از
localhostبه یک دامنه یا IP عمومی منتقل میشود. پورت هم دیگر داخلی نیست. - پروسه: برنامه باید جایی اجرا شود که بعد از بستن ترمینال یا ریاستارت سرور هم زنده بماند. ترمینال تو مدیر پروسه نیست.
- پیکربندی: دیتابیس، کلیدها، مسیر فایلها و حالت اجرا (Production) با محیط توسعه فرق دارند و باید از بیرون به برنامه داده شوند.
برای همین عبارت «روی سیستم من کار میکرد» یک شوخی رایج نیست، یک نتیجهٔ منطقی است: نسخهٔ زبان، وابستگیهای نصبشده، متغیرهای محیطی و دسترسی شبکه در سرور با لپتاپ تو یکسان نیست. دیپلوی حرفهای یعنی این تفاوتها را از قبل حذف کنی.
دیپلوی یعنی کد از حالت «مال من» به «مال همه» تبدیل شود. همین تغییر مالکیت، تقریباً همهٔ پیچیدگیها را میسازد.
چرا اصلاً دیپلوی کنیم؟
- بازخورد واقعی: تا پروژه آنلاین نباشد، کسی جز خودت آن را روی دستگاه واقعی امتحان نکرده است.
- تحویل قابل بررسی: به جای فرستادن سورس یا بردن لپتاپ به جلسه، یک لینک میفرستی و کارفرما همان لحظه میبیند.
- پیدا شدن باگهای محیطی: اختلاف سیستمعامل، فونت، منطقهٔ زمانی و شبکه فقط در محیط واقعی خودش را نشان میدهد.
- چرخهٔ کوتاهتر: وقتی دیپلوی یک فرایند تکراری و خودکار باشد، انتشار نسخهٔ جدید از یک پروژهٔ ترسناک به یک کار چند دقیقهای تبدیل میشود.
- اعتماد: آدرس فعال با HTTPS، قبل از هر توضیحی، نشان میدهد کار جدی است.
دیپلوی با انتشار، هاستینگ و CI/CD چه تفاوتی دارد؟
این چهار کلمه در گفتگوهای روزمره قاطی میشوند، اما یکی نیستند و قاطی شدنشان تصمیمهای اشتباه میسازد.
| مفهوم | چه کاری میکند | خروجی |
|---|---|---|
| Build | سورس را به نسخهٔ قابل اجرا تبدیل میکند | فایلهای خروجی یا ایمیج Docker |
| Deploy | آن خروجی را روی محیط اجرا مستقر میکند | یک نسخهٔ در حال اجرا روی سرور |
| Release | قابلیت را برای کاربر فعال میکند | تغییر قابل مشاهده برای کاربر |
| Hosting | زیرساخت و منابع را فراهم میکند | سرور، دیسک، پهنای باند، پنل |
| CI/CD | زنجیرهٔ تست و انتشار را خودکار میکند | پایپلاین و دیپلوی خودکار |
| Provisioning | زیرساخت را از صفر آماده میکند | ماشین، شبکه، دیتابیس |
مهمترین تفکیک، Deploy و Release است. میتوانی نسخهٔ جدید را دیپلوی کنی اما قابلیتش را با یک Feature Flag خاموش نگه داری و بعداً روشنش کنی. این کار ریسک را نصف میکند: کد آنجاست، ولی رفتار سیستم عوض نشده است.
همچنین دیپلوی فقط کپی فایل نیست. اگر وابستگی نصب نشود، دیتابیس مهاجرت نکند، پروسه ریاستارت نشود یا ترافیک به نسخهٔ قدیمی برسد، فایلها سرجایشان هستند اما سرویس کار نمیکند. این تفاوت بین «آپلود کردم» و «دیپلوی کردم» است.
در دیپلوی واقعاً چه اتفاقی میافتد؟
هر روشی را انتخاب کنی، این هفت مرحله با اسمهای مختلف تکرار میشوند. وقتی دیپلوی خراب میشود، مشکل تقریباً همیشه در یکی از همین حلقههاست.
- بیلد
- خروجی
- انتقال
- پیکربندی
- اجرا
- بررسی سلامت
- سوییچ ترافیک
- Build: وابستگیها نصب و کد کامپایل یا باندل میشود. بدون فایل قفل نسخهها، هر build میتواند نتیجهٔ متفاوتی بدهد.
- خروجی: نتیجه یک ایمیج Docker یا یک پوشهٔ dist است. این خروجی باید تغییرناپذیر باشد؛ یعنی همان بایتها بعداً هم قابل استقرار باشند.
- انتقال: ایمیج به رجیستری push میشود یا فایلها با rsync/SFTP کپی میشوند. اینجا هنوز چیزی برای کاربر عوض نشده است.
- پیکربندی: متغیرهای محیطی، کلیدها و رشتهٔ اتصال دیتابیس تنظیم میشوند. بهترین حالت این است که این اطلاعات در کد نباشند.
- اجرا: پروسه با یک مدیر پروسه یا کانتینر بالا میآید. بدون سیاست ریاستارت، اولین کرش یعنی سرویس خاموش.
- بررسی سلامت: یک درخواست به مسیر مشخص (مثل
/health) فرستاده میشود. اگر جواب ۲۰۰ نیامد، نسخهٔ جدید سالم نیست و نباید ترافیک بگیرد. - سوییچ ترافیک: بالانسر، پروکسی معکوس یا DNS ترافیک را به نسخهٔ جدید میفرستد. این آخرین قدم است، نه اولین قدم.
اگر فقط یک چیز از این بخش یادت بماند، همین باشد: ترافیک را وقتی سوییچ کن که نسخهٔ جدید جواب داده باشد. خیلی از قطعیها به این دلیل اتفاق میافتند که ترافیک قبل از آماده شدن سرویس منتقل میشود.
پنج روش دیپلوی و جاهایی که هرکدام میشکنند
۱. دیپلوی دستی با FTP یا SSH
فایلها را با FTP/SFTP آپلود میکنی یا با rsync و ssh روی سرور کپی میکنی، بعد سرویس را ریاستارت میکنی. این روش هنوز در هاست اشتراکی و پروژههای کوچک رایج است و برای یک فایل HTML سریعترین راه است.
مشکلش این است که هیچجا ثبت نمیشود چه چیزی روی سرور است. یک فایل جاافتاده، یک نسخهٔ قدیمی که پاک نشده، یا تفاوت بین سرور اصلی و تستی، کمکم جمع میشود و در بدترین زمان خودش را نشان میدهد.
۲. VPS با Docker
یک سرور مجازی میگیری و اپلیکیشن را در کانتینر اجرا میکنی. کنترل کامل داری: میتوانی ورکر، کرونجاب، ردیس و هر سرویس جانبی را کنارش بالا بیاوری. در مقابل، مسئولیت بهروزرسانی سیستمعامل، فایروال، گواهی SSL، بکاپ و مانیتورینگ هم با خودت است.
حداقلِ قابلقبول این روش، Docker Compose با ایمیج تگدار و restart: unless-stopped است؛ نه اجرای دستی کانتینر با docker run که بعد از ریاستارت سرور فراموش میشود.
۳. پلتفرم PaaS با git push
ریپو را به پلتفرم وصل میکنی، شاخه را انتخاب میکنی و پلتفرم build و اجرا را انجام میدهد. تو فقط پورت و متغیرهای محیطی را اعلام میکنی. نتیجه معمولاً یک آدرس HTTPS آماده است.
این روش برای تیمی که DevOps اختصاصی ندارد بهترین نسبت هزینه به دردسر است. نقطهٔ ضعفش کنترل کمتر روی جزئیات زیرساخت و وابستگی به پلتفرم است؛ پس قبل از انتخاب، بدان که مهاجرت بعدی چقدر هزینه دارد.
۴. سایت استاتیک روی CDN
اگر خروجی پروژه فقط HTML، CSS، JS و تصویر است، نیازی به سرور برنامه نداری. فایلها را در فضای ذخیرهسازی یا CDN میگذاری و یک آدرس میگیری. سرعت بالا، هزینهٔ نزدیک به صفر و سطح حملهٔ کوچک، مزیت اصلی این روش است. وبلاگ، لندینگ و مستندات بهترین گزینهاند.
۵. سرورلس
کد را بهصورت تابع منتشر میکنی و پلتفرم فقط وقتی درخواست میآید آن را اجرا میکند. برای بار نامنظم و کارهای کوتاه عالی است، اما برای پروسههای طولانی، اتصال دائمی دیتابیس یا وبسوکت محدودیت دارد.
| روش | دانش لازم | کنترل | هزینه | سرعت شروع | مناسب برای |
|---|---|---|---|---|---|
| دستی | کم | زیاد | کم | فوری | فایل استاتیک، پروژهٔ کوچک |
| VPS + Docker | متوسط تا زیاد | کامل | ماهانهٔ ثابت | نیم روز | سرویس با چند جزء |
| PaaS | کم | محدود | ساعتی | چند دقیقه | MVP و محصول در حال رشد |
| استاتیک + CDN | کم | کم | نزدیک صفر | چند دقیقه | وبلاگ، لندینگ، مستندات |
| سرورلس | متوسط | کم | بهازای فراخوانی | چند دقیقه | بار نامنظم و API سبک |
کدام روش برای پروژهٔ تو درست است؟
قاعدهٔ ساده: سادهترین روشی را انتخاب کن که هنوز جواب میدهد، و پیچیدگی را وقتی اضافه کن که واقعاً به آن رسیدهای. راهاندازی Kubernetes برای هزار کاربر اول، مهندسی بیش از حد است و فقط وقت توسعه را میخورد.
- وبلاگ، لندینگ، مستندات: استاتیک روی CDN. بدون سرور برنامه، بدون ریسک کرش.
- MVP با کاربر ایرانی و بدون تیم زیرساخت: PaaS داخلی. HTTPS و آدرس آماده است و تمرکزت روی محصول میماند.
- پروژهای با ورکر، کرونجاب، ردیس و تونل: VPS با Docker. اینجا کنترل کامل ارزش پول و وقتش را دارد.
- ترافیک نامنظم و کم: سرورلس، تا وقتی هزینهٔ هر فراخوانی از هزینهٔ یک سرور بیکار کمتر باشد.
اگر بین IaaS و PaaS مردد هستی، سرویس PaaS چیست و کِی بهتر از سرور است و هاست یا VPS را ببین. آن دو مقاله دقیقاً همین تصمیم را باز کردهاند.
قبل از دیپلوی، پروژه باید چه چیزی داشته باشد؟
بیشتر مشکلات دیپلوی از کد نیست، از نبودِ سه چیز است: پورت قابل تنظیم، متغیر محیطی و بررسی سلامت. اینها را یکبار درست کن، بعد هر روشی را انتخاب کنی جواب میگیری.
یک Dockerfile تمیز و قابل تکرار
الگوی زیر برای یک پروژهٔ Node دو مرحله دارد: مرحلهٔ build وابستگیهای کامل را نصب میکند، مرحلهٔ اجرا فقط خروجی نهایی و وابستگیهای پروداکشن را میبرد. نتیجه ایمیج کوچکتر و سطح حملهٔ کمتر است.
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine AS runtime
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=build /app/dist ./dist
EXPOSE 3000
USER node
CMD ["node", "dist/server.js"]دو نکته که فراموش میشوند: npm ci به فایل قفل نیاز دارد و بدون آن خطا میدهد (که خوب است، چون build را تکرارپذیر میکند)، و USER node جلوی اجرای برنامه با کاربر root داخل کانتینر را میگیرد.
اگر build به رجیستری خارجی دسترسی ندارد یا با خطای ۴۰۳ روی pull متوقف میشود، بیسایمیج را از رجیستری داخلی بگیر و همان Dockerfile را دوباره اجرا کن؛ مثلاً repo.lexoya.com/lexoya/node-base-image:20 به جای node:20-alpine.
پورت را از محیط بخوان، روی 0.0.0.0 گوش کن
دو خطای کلاسیک: پورت داخل کد ثابت شده است و برنامه فقط روی 127.0.0.1 گوش میدهد. در کانتینر، لوکالهاست یعنی خود کانتینر؛ پس از بیرون هیچکس نمیتواند وصل شود و نتیجهاش خطای ۵۰۲ است.
import express from "express";
const app = express();
const port = Number(process.env.PORT ?? 3000);
app.get("/health", (_req, res) => res.status(200).send("ok"));
app.listen(port, "0.0.0.0", () => {
console.log("listening on " + port);
});پلتفرمها معمولاً پورت را از متغیر محیطی میدهند. اگر پورت را در کد سخت کنی، برنامه بالا میآید اما هیچ درخواستی دریافت نمیکند.
یک مسیر سلامت واقعی
بررسی سلامت باید بگوید «برنامه میتواند درخواست بگیرد»، نه «سرور روشن است». یک مسیر مثل /health که ۲۰۰ برگرداند کافی است. اگر دیتابیس هم حیاتی است، آن را در مسیر جداگانهای (readiness) چک کن تا قطعی دیتابیس باعث ریاستارت بیپایان برنامه نشود.
دیپلوی بدون قطعی و برگشت به عقب
«دیپلوی بدون قطعی» جادو نیست؛ یعنی نسخهٔ جدید را جایی بالا بیاوری که هنوز ترافیک نمیگیرد، مطمئن شوی سالم است، بعد ترافیک را ببری. چهار الگوی رایج:
- Recreate: نسخهٔ قبلی خاموش، نسخهٔ جدید روشن. ساده و برای پروژهٔ شخصی کافی، اما چند ثانیه قطعی دارد.
- Rolling: نمونهها یکییکی جایگزین میشوند. سرویس همیشه چند نمونهٔ سالم دارد.
- Blue-Green: دو محیط کامل داری و ترافیک یکجا از آبی به سبز میرود. برگشت به عقب هم فقط یک سوییچ است.
- Canary: درصد کمی از ترافیک به نسخهٔ جدید میرود و با پایش خطا، کمکم زیاد میشود.
پایهٔ همهٔ اینها یک چیز است: خروجی تغییرناپذیر. اگر هر بار از سورس build کنی، «برگشت به نسخهٔ قبلی» یعنی یک build جدید با نتیجهٔ نامعلوم. اما وقتی هر نسخه یک ایمیج با تگ کامیت است، برگشت یعنی استقرار همان ایمیج قبلی، در چند دقیقه و بدون سورپرایز.
برای دیتابیس، قاعدهٔ expand و contract را رعایت کن: اول ستون یا جدول جدید را اضافه کن (سازگار با کد قدیمی)، بعد کد جدید را دیپلوی کن، بعد داده را پر کن و در نسخهٔ بعدی چیزهای قدیمی را حذف کن. مهاجرتهای سنگین و تغییر نام ستون در یک قدم، همان چیزی است که دیپلوی را به قطعی تبدیل میکند.
خطاهای رایج دیپلوی و راهحلشان
| نشانه | علت احتمالی | کار درست |
|---|---|---|
| روی لپتاپ کار میکند، روی سرور نه | نسخهٔ زبان یا وابستگی متفاوت است | فایل قفل را کامیت کن، نسخه را پین کن، لاگ استارتاپ را بخوان |
| خطای ۵۰۲ یا ۵۰۴ بعد از دیپلوی | پروسه گوش نمیدهد یا پورت اشتباه است | پورت را از PORT بخوان و روی 0.0.0.0 گوش کن |
| کانتینر بلافاصله exit میشود | دستور شروع یا متغیر ضروری وجود ندارد | لاگ کانتینر را ببین، متغیرها را کامل کن |
| build با خطای فایل قفل متوقف میشود | نسخهٔ قفل کامیت نشده است | npm ci نیاز به lockfile دارد؛ آن را کامیت کن |
| pull ایمیج با ۴۰۳ رد میشود | محدودیت یا تحریم رجیستری | بیسایمیج را از رجیستری داخلی بگیر و دوباره build کن |
| اتصال به دیتابیس برقرار نمیشود | رشتهٔ اتصال روی localhost مانده است | از آدرس داخلی پلتفرم یا سرویس دیتابیس استفاده کن |
| فایلهای آپلودی بعد از دیپلوی پاک میشوند | فایلسیستم کانتینر موقتی است | فایل را در S3 یا یک والیوم پایدار ذخیره کن |
| نسخهٔ قدیمی سرو میشود | کش CDN، مرورگر یا سرویسورکر | نام فایل را هشدار کن و کش HTML را کوتاه بگذار |
| سرویس با مصرف حافظه کشته میشود | نشت حافظه یا محدودیت منابع | مصرف را پایش کن، محدودیت را واقعبینانه بگذار |
| دامنه باز نمیشود یا SSL خطا میدهد | رکورد DNS اشتباه یا propagation ناتمام | رکورد A/CNAME را درست کن و TTL را کم بگیر |
چکلیست امنیت دیپلوی
- هیچ رمزی در ریپو نباشد. فایل
.envرا در.gitignoreبگذار و اگر قبلاً کامیت شده، تاریخچه را هم پاک کن؛ تغییر فایل کافی نیست. - کمترین دسترسی. کاربر دیتابیس برنامه نباید ادمین باشد و کانتینر نباید با root اجرا شود.
- HTTPS اجباری. بدون گواهی معتبر، نه اعتماد کاربر را داری نه بخشی از سئو را.
- بکاپ قابل بازیابی. بکاپی که تست بازیابی نشده، بکاپ نیست.
- بهروزرسانی وابستگیها. پکیج قدیمی، آسیبپذیری شناختهشده دارد؛ اسکن دورهای را جدی بگیر.
- لاگ بدون دادهٔ حساس. توکن و شماره کارت را در لاگ ننویس.
دیپلوی برای کاربر ایرانی: چیزهایی که در آموزشها نمیگویند
انتخاب محل دیپلوی برای کاربر ایرانی فقط بحث قیمت نیست. سه عامل دیگر هم هست که در تجربهٔ نهایی خیلی بیشتر از پلن سرور اثر میگذارد.
- تأخیر شبکه: هر درخواست باید مسیر طولانیتری طی کند. برای صفحهای که چند درخواست پشتسرهم میزند، این اختلاف جمع میشود و کاربر آن را حس میکند.
- دسترسی به رجیستری و API: بعضی سرویسها برای IP ایران محدودیت دارند. این میتواند build را متوقف کند یا بخشی از محصول را از کار بیندازد.
- پایداری دسترسی: دامنه و IP خارجی همیشه در دسترس کاربر ایرانی نیست. این ریسک را باید در انتخاب زیرساخت حساب کنی.
- پرداخت: هزینهٔ ارزی و کارت بینالمللی خودش یک پروژهٔ جداگانه است.
جمعبندی عملی: اگر مخاطبت داخل ایران است، میزبانی داخلی انتخاب پیشفرض باشد. اگر پروژه به سرویس تحریمشده مثل OpenAI یا Stripe وصل میشود، محیط خارجی لازم داری. در لکسویا این دو حالت کلاستر جدا دارند و دادهها بینشان همگام نمیشوند، پس از اول تصمیم درست را بگیر.
دیپلوی در لکسویا در عمل
اگر روش PaaS را انتخاب کنی، مسیر دیپلوی در لکسویا اینطور است:
- حساب گیت (GitHub، GitLab یا Gitea) را وصل کن و ریپو و شاخه را انتخاب کن.
- اگر ریپو Dockerfile دارد، همان مسیر را بده. اگر ندارد، یک Dockerfile مناسب پروژه بساز و در ریشهٔ ریپو پوش کن.
- پورت کانتینر را مشخص کن (بین ۱ تا ۶۰۰۰۰). این عدد باید همان پورتی باشد که برنامه روی آن گوش میدهد.
- دیپلوی شروع میشود: کلون، build، push ایمیج و استقرار. هر مرحله لاگ جدا دارد؛ اگر جایی شکست خورد، لاگ همان مرحله را بخوان، نه حدس بزن.
- بعد از موفقیت، پروژه یک سابدامین HTTPS رایگان میگیرد و آمادهٔ استفاده است.
چند نکته که در عمل به کار میآید:
- دیپلوی دستی یا خودکار: اگر میخواهی هر push مستقیم به پروداکشن نرود، حالت دیپلوی دستی را روشن کن. تفاوت این دو حالت را در مقالهٔ CI/CD باز کردهایم.
- دیتابیس مدیریتشده: به جای اجرای دیتابیس داخل کانتینر پروژه، یک دیتابیس مدیریتشده بساز و از آدرس داخلی و پورت آن در متغیر
DATABASE_URLاستفاده کن. بکاپ شبانه و نگهداری هم خودکار میشود. - خطاهای build: خطای ۴۰۳ روی pull از Docker Hub معمولاً موقتی است؛ یکبار دیگر تلاش کن. اگر تکرار شد، بیسایمیج را به رجیستری
repo.lexoya.comتغییر بده. - دیپلوی از دستیار: اگر از کلود، کرسر یا opencode استفاده میکنی، سرور MCP لکسویا همین مراحل را بهصورت ابزار در اختیارت میگذارد؛ از ساخت پروژه تا خواندن لاگ پایپلاین. جزئیاتش در مقالهٔ سرور MCP لکسویا است.
مدل هزینه هم ساده است: پرداخت ساعتی و بهازای مصرف، با ۱۰۰ هزار تومان اعتبار اولیه هنگام ثبتنام و یک سابدامین رایگان برای هر پروژه.
اولین دیپلوی را همین امروز انجام بده
ریپو را وصل کن، پورت را بده و آدرس HTTPS پروژه را بگیر. اگر پروژه Dockerfile ندارد، از الگوی همین مقاله استفاده کن.
چکلیست قبل از اولین دیپلوی
- فایل قفل وابستگیها کامیت شده است.
- پورت از متغیر محیطی خوانده میشود و روی
0.0.0.0گوش میدهد. - مسیر
/healthکد ۲۰۰ برمیگرداند. - همهٔ متغیرهای محیطی لازم فهرست شدهاند و هیچ رمزی در ریپو نیست.
- Dockerfile یا دستور build مشخص و تکرارپذیر است.
- مهاجرت دیتابیس سازگار با نسخهٔ قبلی است.
- قبل از مهاجرت، بکاپ گرفتهای.
- میدانی اگر خراب شد چطور به نسخهٔ قبلی برگردی.
- لاگ و مانیتورینگ جایی وصل است که واقعاً ببینی.
- دامنه و HTTPS قبل از اعلام آدرس به کاربر تست شده است.
deploy = build -> artifact -> configure -> run -> health check -> route traffic
artifact must be immutable (docker image tagged with commit)
port from env, listen on 0.0.0.0, expose /health
rollback = redeploy previous image, not rebuild
zero-downtime = new version up first, traffic switched after health check
never store secrets in the repo; use environment variablesسؤالات متداول
دیپلوی چیست، به زبان ساده؟
دیپلوی یعنی نسخهای از پروژه را از محیط توسعه به محیطی منتقل کنی که کاربر واقعی بتواند از طریق یک آدرس به آن دسترسی داشته باشد. این کار فقط کپی فایل نیست: کد باید build شود، وابستگیها و متغیرهای محیطی درست تنظیم شوند، پروسه اجرا شود و بعد ترافیک به آن برسد.
تفاوت دیپلوی (Deploy) و انتشار (Release) چیست؟
دیپلوی یعنی نصب نسخه روی محیط اجرا؛ انتشار یعنی فعال شدن آن برای کاربر. این دو میتوانند جدا باشند: کد را دیپلوی میکنی ولی قابلیت جدید را با Feature Flag خاموش نگه میداری و بعداً روشنش میکنی. همین جداسازی، دیپلوی را کمریسک میکند.
دیپلوی با هاستینگ چه فرقی دارد؟
هاستینگ زیرساخت است (سرور، فضای دیسک، پنل)؛ دیپلوی فرایندی است که پروژه را روی آن زیرساخت مستقر میکند. یعنی هاست را یکبار میخری، اما دیپلوی را با هر نسخهٔ جدید تکرار میکنی.
اولین قدم برای دیپلوی یک پروژه چیست؟
پروژه را قابلاجرا و قابلتکرار کن: فایل قفل وابستگیها (مثل package-lock.json) را کامیت کن، پورت را از متغیر محیطی بخوان، مسیر سلامت مثل /health بگذار، هیچ رمزی را در ریپو نگه ندار و یک Dockerfile یا دستور build مشخص داشته باش. بعد از این، انتخاب روش دیپلوی ساده میشود.
دیپلوی بدون قطعی (Zero-Downtime) چطور انجام میشود؟
نسخهٔ جدید را کنار نسخهٔ قبلی بالا میآوری، تا وقتی بررسی سلامت (Health Check) جواب ۲۰۰ بدهد ترافیک را نمیفرستی، بعد ترافیک را سوییچ میکنی و نسخهٔ قبلی را نگه میداری. این همان الگوی Blue-Green است؛ Rolling و Canary نسخههای تدریجی همین ایدهاند.
اگر دیپلوی خراب شد، چطور به نسخهٔ قبلی برگردیم؟
بهترین راه، استقرار دوبارهٔ همان خروجی قبلی است، نه git revert و build مجدد. به همین دلیل هر نسخه باید یک خروجی تغییرناپذیر (Docker Image با تگ کامیت) داشته باشد تا Rollback یک عمل چند دقیقهای باشد.
برای کاربر ایرانی کجا دیپلوی کنم؟
اگر مخاطب داخل ایران است، میزبانی داخلی تأخیر شبکه و ریسک قطع دسترسی را کم میکند. اگر پروژه به سرویس تحریمشده مثل OpenAI یا Stripe وصل میشود، کلاستر خارجی لازم است. سایت استاتیک هم میتواند روی CDN بماند، به شرطی که دسترسی به آن پایدار باشد.
آیا برای دیپلوی حتماً به Docker نیاز دارم؟
نه. پروژهٔ کوچک با systemd یا PM2 روی VPS هم اجرا میشود و سایت استاتیک فقط به آپلود فایل نیاز دارد. اما Docker محیط را تکرارپذیر میکند و همین باعث میشود تفاوت «روی لپتاپ کار میکرد» کمتر پیش بیاید؛ به همین دلیل بیشتر پلتفرمها و ابزارهای امروزی حول ایمیج کار میکنند.
دیپلوی چقدر زمان میبرد و چه هزینهای دارد؟
سایت استاتیک در چند ثانیه منتشر میشود؛ پروژهٔ کانتینری معمولاً یکی دو دقیقه build و اجرا دارد. هزینه هم به روش بستگی دارد: استاتیک تقریباً رایگان، PaaS ساعتی و بهازای مصرف، و VPS ماهانه با منابع ثابت.
منابع
- The Twelve-Factor App، بهخصوص بخشهای build/release/run و پیکربندی از محیط.
- مستندات multi-stage build داکر، الگوی Dockerfile این مقاله.
- BlueGreenDeployment، توضیح الگوی دیپلوی بدون قطعی.
- Deployment در Kubernetes، مرجع rolling update و بررسی سلامت.
مطالب مرتبط
- دیپلوی لاراول اگر پروژهات لاراول است و صف، migrations و وبسوکت هم دارد.
- CI/CD چیست؟ برای خودکار کردن همین مراحل و انتخاب بین دیپلوی دستی و خودکار.
- داکر چیست؟ اگر میخواهی مفهوم ایمیج و کانتینر را از پایه ببندی.
- تفاوت PaaS و IaaS برای انتخاب بین سرور و پلتفرم.
- میزبانی استاتیک برای سایتهایی که اصلاً سرور برنامه لازم ندارند.
- دسترسپذیری بالا برای وقتی دیپلوی بدون قطعی کافی نیست.