گردو امروز کجاست و به کجا میرود؟
تابستان ۱۴۰۵ برای گردو فصل یکپارچهکردن محصول و محکمکردن زیرساخت بود؛ از مدل واحد سرویس و استقرار از گیت تا CLI، MCP، کوبرنتیز و توسعهی سرور ابری. در این گزارش میگوییم چه ساختیم، چه چیزهایی یاد گرفتیم و تمرکز بعدی گردو روی چه مسائلی است.
تابستان ۱۴۰۵ برای گردو بیشتر از آنکه فصل اضافهکردن چند قابلیت تازه باشد، فصل پیدا کردن شکل واقعی محصول بود.
ما تابستان را با چند مسیر نسبتاً جدا شروع کردیم: سرور ابری، اپلیکیشنهای مبتنی بر Git، کانتینرها و ابزارهایی که هرکدام مدل ذهنی خودشان را داشتند.
امروز تصویر سادهتر شده است:
کد، Docker Image یا یک نرمافزار آماده را به گردو بدهید؛ باقی مسیر اجرا را تا جای ممکن به ما بسپارید.
رسیدن به این سادگی، البته ساده نبود.
در سه ماه گذشته بیش از هزار تغییر در مخزن اصلی گردو ثبت شد. بعضی از آنها چیزهایی هستند که مستقیم میبینید: CLI، محیطهای آزمایشی، ظاهر تازهی پنل یا قابلیتهای بیشتر سرور ابری.
اما بخش بزرگی از کار جایی اتفاق افتاد که امیدواریم مجبور نباشید زیاد دربارهاش فکر کنید: صف بیلد، شبکه، مالی، Volumeها، ماگریشنها، ریکاوری، لاگها و کنترلرهایی که باید شبانهروز کار کنند و وقتی همهچیز درست است، تقریباً دیده نمیشوند.
این نوشته دربارهی تعداد قابلیتهایی که در محصول ریلیز کردیم نیست.
دربارهی این است که گردو در این سه ماه چه شکلی پیدا کرد، کجا فهمیدیم مسیر قبلی درست نیست، چه چیزهایی ساختیم و از اینجا به بعد روی چه چیزهایی باید سختگیرتر باشیم.
خلاصهی خیلی کوتاه
اگر قرار نیست تمام این نوشته را بخوانید، تابستان گردو را میشود اینطور خلاصه کرد:
- «اپلیکیشن» و «کانتینر» دیگر دو مفهوم جدا نیستند. هر دو حالا سرویس هستند و درون یک پروژه کنار دیتابیس، ورکر، برنامههای زمانبندیشده و بقیهی اجزای محصول زندگی میکنند.
- مسیر Git push تا یک سرویس در حال اجرا کاملتر شد؛ از بیلد و لاگ زنده تا ریلیز، بازگردانی، محیط و پیشنمایش برای Pull Requestها.
- CLI از یک دستور Deploy فراتر رفت و به یکی از رابطهای اصلی گردو تبدیل شد. MCP هم اضافه شد تا Agentها بتوانند با اجازهی شما با پلتفرم کار کنند.
- لایهی اجرای سرویسها به کوبرنتیز منتقل شد؛ همراه با شبکه، Volume، کران، متریکها، حسابوکتاب و انتقال واقعی اپلیکیشنها و کانتینرها.
- ابرک، دیاناس، بکاپگیری، فایروال، کنسول و مدل اتصال به چند دیتاسنتر خارجی گسترش پیدا کرد.
- پنل، وبسایت، مستندات و وبلاگ را بازطراحی کردیم؛ چون قابلیتهایی که پیدا کردن و فهمیدنشان سخت باشد، عملاً نصفهاند.
و مهمتر از همه، تمرکز بعدیمان روشنتر شده:
Reliability و Core Product Loop.
یعنی پلتفرم قابل اتکاتر شود و فاصلهی میان «کد من آماده است» تا «سرویس من سالم و آنلاین است» کوتاهتر، قابل فهمتر و کماصطکاکتر شود.
قولی که گردو با آن شروع شد
ایدهی اولیهی گردو خیلی پیچیده نبود:
راهاندازی و نگهداری زیرساخت نباید بخش بزرگی از زمانی را که برای ساخت محصول دارید، مصرف کند.
برای یک تیم ایرانی این مسئله فقط دربارهی انتخاب AWS یا Kubernetes نیست.
قبل از آنکه اولین کاربر وارد محصول شود، ممکن است مجبور باشید سرور بخرید، شبکه تنظیم کنید، SSL راه بیندازید، راهی برای دسترسی به رجیستریها و پکیجمنیجرها پیدا کنید، پرداخت ارزی انجام دهید، دیتابیس نگه دارید، بکاپ بگیرید و یک پایپلاین برای دیپلوی بسازید.
هیچکدام از این کارها لزوماً بیاهمیت نیستند.
اما برای بیشتر تیمها، هیچکدام هم محصول نیستند.
قراردادی که میخواهیم گردو با توسعهدهنده داشته باشد ساده است:
شما محصول را بسازید. گردو کد را بیلد کند، اجرا کند، به شبکه وصل کند و ابزار لازم برای نگهداری آن را در اختیارتان بگذارد.
سرور ابری همچنان بخش مهمی از این تصویر است. گاهی دقیقاً یک ماشین کامل میخواهید و باید کنترل آن ماشین دست خودتان باشد.
اما در بسیاری از پروژهها هدف نهایی «داشتن یک سرور» نیست.
هدف این است که یک ایپیآی، ورکر، دیتابیس یا اپلیکیشن را اجرا کنید و مطمئن باشید فردا هم کار میکند.
بخش بزرگی از کار این تابستان صرف نزدیکتر شدن به همین قرارداد شد.
چه چیزهایی خوب پیش رفت؟
یک پروژه، چند سرویس، یک مدل ذهنی
در نسخههای قبلی گردو، اپلیکیشنهای مبتنی بر Git و کانتینرهای همیشهروشن دو دنیای متفاوت بودند.
این تفاوت فقط در بکاند نبود. به ایپیآی، دشبورد کاربران، نوع پرداختها و حتی واژههایی که در محصول استفاده میکردیم سرایت کرده بود.
در نتیجه، کاربر قبل از دیپلوی کردن محصولش باید بخشی از معماری داخلی گردو را یاد میگرفت.
این نشانهی خوبی نبود.
پس مدل قبلی را کنار گذاشتیم.
امروز واحد اصلی اجرا در گردو سرویس است.
یک سرویس میتواند از ریپو گیت، داکر ایمیج، فایلهای لوکال یا تمپلیت آماده در بازارچه ساخته شود.
پروژه هم ظرف مشترکی است که سرویسها، متغیرها، محیطهای مختلف، افزونهها، اعضای تیم و شبکه خصوصی را کنار هم قرار میدهد.
در ظاهر شاید این فقط تغییر چند اسم به نظر برسد.
نبود.
APIها، دشبورد، پایپلاین بیلد ، رانتایم، دامنهها، محاسبهی مصرف و دادههای موجود باید به مدل جدید منتقل میشدند.
اما نتیجه چیزی است که از ابتدا باید داشتیم:
ساخت یک ایپیآی از گیت، اجرای ورکر از یک ایمیج و اضافهکردن PostgreSQL به همان پروژه دیگر سه workflow بیربط نیستند.
همه بخشی از یک سیستماند.
و این برای خود ما هم مهم است. حالا وقتی قابلیت جدیدی مثل متریکها، متغیرها یا حسابداری میسازیم، آن را برای یک مفهوم مشترک میسازیم؛ نه چند بار برای چند مدل اجرای موازی.
فاصلهی git push تا یک آدرس واقعی کوتاهتر شد
اینتگریشن گیت در گردو دیگر فقط راهی برای کلون کردن ریپازیتوری نیست.
پوش روی یک برنچ میتواند دیپلوی تازهای را شروع کند. دیپلوی به کامیت مربوط میشود. وبهوک دیپلوی اجازه میدهد CI خارجی همان چرخه را فعال کند.
برای بیلدها لاگ زنده داریم. Artifact و ریلیز نگه داشته میشوند. اگر نسخهی جدید خوب کار نکرد، میتوانید بازگردانی کنید.
استقرار جدید هم نباید فقط به این دلیل که نسخهی قبلی در حال اجراست، باعث داونتایم شود.
در پشت صحنه یک مسئلهی کمتر جذاب ولی مهم دیگر هم وجود دارد: اگر چند بیلد پشت سر هم برسند، بیلد قدیمی نباید منابع صف را برای کامیتی اشغال کند که دیگر آخرین نسخه نیست.
اینها جزئیاتی هستند که یک دیپلوی واقعی را از دکمهی نمایشی «دیپلوی» جدا میکنند.
محیطهای آزمایشی برای Pull Requestها هم به همین چرخه اضافه شد.
هدف ساده است:
فاصلهی میان
«روی لپتاپ من کار میکند»
و
«میتوانم این تغییر را در محیطی واقعی بررسی کنم»
باید تا جای ممکن کوتاه باشد.
برای Monorepoها هم Dockerfile Path، Build Context و Watch Path قابل تنظیم شدند.
شاید قابلیتهای جذابی برای صفحهی اصلی سایت نباشند، اما اگر یک Monorepo واقعی داشته باشید، دقیقاً همین جزئیات تعیین میکنند یک پلتفرم برای دمو خوب است یا برای پروداکشن.
ترمینال به یک رابط درجهیک تبدیل شد
اولین نسخهی CLI گردو در خرداد منتشر شد.
ایده در ابتدا کوچک بود: برای دیپلوی کردن یک پوشهی لوکال نباید الزاماً GitHub یا GitLab وسط کار باشد.
با gerdoo deploy میتوانید پوشهی فعلی را به یک سرویس وصل کنید، کد را بفرستید و دیپلوی را شروع کنید.
اما CLI خیلی زود بزرگتر از این شد.
امروز از طریق آن میتوان پروژه، سرویس، متغیر، دامنه، بیلد، ریلیز، لاگ، فایل و Rollback را مدیریت کرد.
انتشار برای سیستمعاملها و معماریهای مختلف و Self-update هم به همان تجربه اضافه شد.
بعد MCP را اضافه کردیم.
این بخش برای ما صرفاً یک اینتگریشن جانبی نیست.
با MCP، ابزارهایی مثل Codex، Claude و Cursor میتوانند (با اجازهی شما) پروژه را ببینند، سرویس بسازند، دیپلوی را بررسی کنند و لاگ بخوانند.
این هنوز نقطهی پایان نیست.
Agentی که فقط میتواند دیپلوی را شروع کند ولی نتواند نتیجهی کار خودش را درست ارزیابی کند، هنوز اوپراتور خوبی نیست.
اما زیرساخت لازم برای این مسیر امروز وجود دارد.
و فکر میکنیم در آینده، توسعهدهنده تنها مصرفکنندهی ایپیآیهای پلتفرم نخواهد بود.
لایهی اجرای سرویسها را روی پایهی جدیتری بردیم
بزرگترین پروژهی زیرساختی این تابستان مهاجرت رانتایم سرویسها به کوبرنتیز بود.
از بیرون ممکن است این کار شبیه این باشد:
«قبلاً کانتینر را با داکر اجرا میکردند، حالا با کوبرنتیز.»
کاش واقعاً همینقدر ساده بود.
اجرای کانتینر تقریباً آسانترین قسمت ماجراست.
یک سرویس باید داخل شبکهی خصوصی پروژه پیدا شود. دامنه و اساسال آن باید بدون قطعی کار کنند. CPU و RAM باید درست محاسبه شوند. Volume نباید هنگام ریلیز جدید گم شود. کران باید سر وقت اجرا شود. افزونهها باید در دسترس بمانند.
و اگر بخشی از این چرخه شکست خورد، پلتفرم باید بداند چه چیزی را دوباره انجام دهد، چه چیزی را نگه دارد و چه زمانی بازگردانی کند.
برای این مهاجرت، کنترلهای Lifecycle، مسیرهای شبکهی پایدار، Stateful Workloadها، شواهد مهاجرت، Volume Fencing، اجرای کران و جمعآوری متریکها و لاگهای دسترسی را ساختیم.
و مهمتر از همه، workloadهای واقعی را مرحلهای منتقل کردیم.
نه با یک سوییچ بزرگ در یک شب و امید به اینکه همهچیز درست باشد.
امروز HTTP Traffic سرویسهای کوبرنتیز از گیتوی میگذرد و همان لایه دادههای مورد نیاز برای متریکها و لاگهای دسترسی را به پلتفرم برمیگرداند.
این دقیقاً از همان دسته کارهایی است که شما نباید مجبور باشید دربارهاش فکر کنید.
و دقیقاً به همین دلیل ما باید زیاد دربارهاش فکر کنیم.
سرور ابری فقط یک دکمهی «ساخت سرور» نیست
در بخش سرور ابری هم بخش زیادی از کار روی کامل کردن چرخهی بعد از ساخت سرور انجام شد.
ساخت سرور پایدارتر و قابل تکرارتر شد و امکاناتی مثل:
- کنسول وب
- دوباره ساختن
- تغییر سایز
- اسنپشات
- بکاپ
- کنترل شبکه
- فایروال
- مشاهدهی ترافیک
- میزان هزینه
اضافه یا کاملتر شدند.
در همین زمان مدل ارائهدهنده را هم گسترش دادیم.
نمیخواهیم گردو به یک ارائهدهندهی زیرساخت یا یک دیتاسنتر محدود باشد.
اتصال Hetzner و Vultr و تعریف یک مدل مشترک برای امکانات ارائهدهندهها قدمهای اولیهی همین مسیر هستند.
ایده این است که منطقه، قیمت و نیاز فنی را انتخاب کنید؛ نه اینکه برای هر ارائهدهنده مجبور شوید یک محصول کاملاً متفاوت یاد بگیرید.
DNS مدیریتشده هم بازسازی شد. نیمسرور دوم روی زیرساخت مستقل قرار گرفت و مدیریت دامنه، رکوردها و ریدایرکت استاندارد www قابل اتکاتر شد.
اینها قابلیتهای جانبی نیستند.
دیپلوی وقتی تمام شده که سرویس واقعاً و پایدار از اینترنت در دسترس باشد.
چه چیزهایی یاد گرفتیم؟
ساخت فیچر بخش آسان داستان است.
قسمت مهمتر این تابستان جاهایی بود که فهمیدیم بعضی فرضهای قبلیمان درست نبودهاند.
۱. اگر محصول ساده است، معماری هم باید این سادگی را باور کند
مدتی تلاش کردیم مدلهای متفاوت اجرای workload را پشت یوآی ساده پنهان کنیم.
اپ یک چیز بود. کانتینر چیز دیگری. پروژه و سرویس هم معنای متفاوت خودشان را داشتند.
مشکل این بود که تفاوت آنها گاهی برای خودمان هم نیاز به توضیح داشت.
میشود پنل را دوباره طراحی کرد.
میشود تولتیپ اضافه کرد.
میشود مستندات نوشت.
اما اگر مدل زیرین پیچیده باشد، یوآی فقط میتواند پیچیدگی را برای مدتی پنهان کند.
ادغام سرویسها کار ارزانی نبود، ولی یک نتیجهی مهم داشت:
امروز قابلیت جدید را یک بار برای یک مدل مشترک میسازیم.
درسش برای ما ساده بود:
اگر برای توضیح مدل اصلی محصول به یک نمودار مفصل نیاز داریم، شاید مشکل از کپیرایتینگ نباشد.
۲. انتقال زیرساخت قبل از هر چیز پروژهی اعتماد است
در مسیر کوبرنتیز بارها به مسئلههایی رسیدیم که در پروتوتایپ دیده نمیشوند.
مسیری که Drift کرده.
Volumeای که فقط میتواند یک Writer داشته باشد.
بیلدی که بعد از ریاستارت بدون صاحب مانده.
کرانجابی که اسمش از محدودیت کوبرنتیز بلندتر شده.
حلقهی پشتیای ای که مدام Fail میشود اما آنقدر آرام که کسی سریع متوجه نمیشود.
هرکدام از اینها ممکن است در تاریخچه گیت فقط یک کامیت کوچک با عنوان fix باشند.
برای کاربری که سرویس پروداکشن او درگیر همان باگ شده، آن کامیت تمام محصول است.
این نگاه باعث شد تعریف ما از محصول کمی تغییر کند.
Health Check محصول است.
Reconciliation محصول است.
Rollback محصول است.
بکاپ محصول است.
دیپلوی بدون داونتایم محصول است.
حتی اگر هیچکدام اسکرینشات هیجانانگیزی برای شبکههای اجتماعی نداشته باشند.
۳. اینترنت ایران یک Edge Case نیست
ساخت نرمافزار در ایران همیشه بهخاطر کد شکست نمیخورد.
گاهی رجیستری در دسترس نیست.
پکیجمنیجر قطع است.
یک مسیر بینالمللی مشکل دارد.
یا سرویس بالادستی تصمیم گرفته درخواست شما را نپذیرد.
اگر پلتفرم فقط در شرایط ایدهآل کار کند، برای کاربران ما پلتفرم کاملی نیست.
این فصل مسیرهای جایگزین داکرهاب و پکیجمنیجرها را گسترش دادیم، Geographic Egress اضافه کردیم و Build Pipeline را طوری تغییر دادیم که شکست یک Dependency بالادستی کل صف را زمین نزند.
هنوز این مسئله را حلشده نمیدانیم.
هدف فقط داشتن چند میرور نیست.
هدف این است که بیلد تا جای ممکن قابل پیشبینی باشد؛ و اگر شکست خورد، دولوپر بتواند بفهمد:
مشکل از کد بود، کانفیگ بود یا شبکه؟
۴. محصول باید بتواند توانایی خودش را توضیح دهد
در انتهای فصل پنل مربوط به پروژه، سرویس و ابرک را با یک زبان بصری مشترک بازطراحی کردیم.
نمای کلی، دامنهها، تنظیمات، تیکتها، سرچ و تفکیک هزینهها هم دوباره مرتب شدند.
وبسایت، مستندات و بلاگ نیز همین مسیر را طی کردند.
این کار برای تفریح نبود.
وقتی بیلد Fail میشود، قدم بعدی باید معلوم باشد.
وقتی هزینه بالا میرود، باید بتوانید بفهمید چرا.
وقتی سرویس در حال انتقال یا بازگردانی است، حالت نباید فقط یک نشان زیبا باشد؛ باید واقعیت را بگوید.
هنوز بخشهایی از این تجربه ناهماهنگ هستند.
اما حالا بهتر میدانیم که پالیش آخر کار نیست.
بخشی از خود محصول است.
از اینجا به بعد کجا میرویم؟
قول اولیهی گردو عوض نشده:
فاصلهی میان کد و یک محصول آنلاین و قابل نگهداری را کوتاه کنیم.
چیزی که تغییر کرده این است که حالا بهتر میدانیم برای عملی کردن این قول، کجا باید سختگیرتر باشیم.
دو محور بیش از همه برایمان مهماند:
اعتماد به پلتفرم، و چرخهی اصلی محصول.
Reliability و Recovery
اولین کار، محکمتر کردن پایهای است که workloadهای واقعی امروز روی آن اجرا میشوند.
Reconciliation بهتر.
Rollout امنتر.
Backup و Restore قابل آزمایش.
رفتار روشنتر Stateful Workloadها.
و حذف Failureهایی که در سکوت اتفاق میافتند.
هدف این نیست که Dependencyهای ما هیچوقت خراب نشوند. چنین قولی واقعی نیست.
هدف این است که وقتی لایهای زیر گردو خراب میشود، تا جای ممکن گردو مشکل را جذب کند؛ نه اینکه معماری خودش را برای دیباگ کردن به کاربر تحویل دهد.
و جایی که نمیتوانیم Failure را پنهان کنیم، باید سریع و واضح بگوییم چه اتفاقی افتاده است.
Core Product Loop
چرخهی اصلی گردو از یک سورس شروع میشود:
Git، پوشه روی دسکتاپ، Docker Image یا تمپلیت.
و باید به یک سرویس سالم ختم شود.
هر توقف غیرضروری میان این دو نقطه، مسئلهی ماست.
روی بیلدها سریعتر و قابل پیشبینیتر، لاگهای خواناتر، تنظیم سادهتر دامنه و متغیر، پیشنمایشهای قابل اتکاتر و بازگردانی امنتر کار خواهیم کرد.
و یک اصل مهم داریم:
Git، CLI، پنل و MCP نباید چهار محصول مختلف باشند.
اینها باید چهار ورودی به یک سیستم مشترک باشند.
اگر چیزی را از CLI ساختهاید، پنل باید دقیقاً همان واقعیت را ببیند.
اگر Agent دیپلوی کرده، شما باید بتوانید بفهمید چه کرده است.
اگر از پنل بازگردانی کردید، CLI نباید داستان دیگری تعریف کند.
یک پلتفرم، چند اینترفیس.
نه چند پلتفرم که اتفاقاً بکاند مشترک دارند.
Observability که به تصمیم برسد
نمودار CPU و RAM مفید است.
اما بهتنهایی جواب دو سؤال مهم را نمیدهد:
«چرا سرویس من کند شده؟»
و:
«چرا هزینهی من بالا رفته؟»
قدم بعدی ما نزدیکتر کردن متریکها، لاگهای دسترسی، دیپلوی ایونتها و هزینه به یکدیگر است.
Observability وقتی ارزشمند میشود که مسیر میان:
چه اتفاقی افتاد؟
و
حالا باید چه کار کنم؟
را کوتاه کند.
این موضوع برای Agentها هم مهم است.
Agentی که دیپلوی میکند اما نمیتواند بررسی کند دیپلوی سالم بوده یا نه، فقط نصف چرخه را دارد.
MCP گردو باید علاوه بر توانایی انجام عملیات، Context لازم برای تایید کردن امن همان عملیات را هم بدهد.
یک ابر بدون مرزهای مصنوعی
ابرک، PaaS، دیتابیس، دیاناس و اپهای بازارچه نباید پنج جزیرهی جدا باشند.
ممکن است API اصلی محصولتان را بهصورت سرویس اجرا کنید، یک workload خاص را روی ابرک نگه دارید و دیتابیس دیگری داشته باشید که باید از طریق شبکه خصوصی به هر دو متصل شود.
از دید شما همهی اینها یک محصولاند.
پلتفرم هم باید همین را بفهمد.
جهتی که دنبال میکنیم این است که چیزهای محاسباتی مختلف بتوانند زیر شبکه، هویت، مالی و پشتیبانی مشترک کنار هم قرار بگیرند.
گسترش ارائهدهندهها و موقعیتها نیز همین هدف را دنبال میکند:
انتخاب بیشتر، بدون تحمیل پیچیدگی بیشتر.
حالا و بعد از این
اولین کامیت این مخزن در ۲۲ مه ۲۰۲۶ ثبت شد.
فاصلهی آن نسخه تا گردوی امروز زیاد است.
اما تعداد کامیتها معیار نهایی موفقیت ما نیست.
سؤالهای مهمتر سادهترند:
آیا یک تیم میتواند سریعتر محصولش را آنلاین کند؟
وقتی چیزی خراب میشود، آیا فهمیدن علت آن ساده است؟
آیا میتواند با بزرگتر شدن محصول همچنان روی گردو بماند؟
و مهمتر از همه:
آیا پلتفرم آنقدر قابل اعتماد است که یک سرویس واقعی را به آن بسپارید؟
در بعضی از این سؤالها پیشرفت زیادی کردهایم.
در بعضی دیگر هنوز فاصله داریم.
رانتایم جدید، CLI و MCP، مدل یکپارچهی سرویسها و پنل تازه برای ما خط پایان نیستند.
اینها پایههایی هستند که اجازه میدهند بخش بعدی را بهتر بسازیم.
اگر از روزهای اول همراه ما بودهاید، بابت صبر، نظرات و اعتمادتان ممنونیم.
اگر جایی گردو شما را معطل کرده، چیزی را خراب کرده یا مجبور شدهاید برای حل مسئله از پلتفرم خارج شوید، دوست داریم بدانیم.
و اگر هنوز برای آوردن یک سرویس واقعی به گردو تردید دارید، آن تردید را جدی میگیریم.
اعتماد با ردمپ ساخته نمیشود.
با تجربهای ساخته میشود که بارها درست کار کند.
تابستان امسال زمان ساختن پایهها بود.
از اینجا به بعد میخواهیم گردو روی این پایهها سریعتر، قابل اتکاتر و در نهایت لذتبخشتر شود.
با مهر، تیم گردو