মূল কনটেন্টে যান
Runs and a deploy's steps in the console

হোস্টেড CI যখন সবচেয়ে ধীর ধাপ হয়ে উঠল, বিল্ডগুলো ঘরে ফিরল

Webanion brand logoWebanionডেভঅপস ইঞ্জিনিয়ারিংআগস্ট 25, 2026 - সেপ্ট 24, 2026২ মাস

বিল্ড আর ডিপ্লয় সরে এসেছে GitHub-এর হোস্টেড রানার থেকে, যেখানে প্রতিটি রান শুরু হতো নতুন মেশিনে আর রিলিজ অপেক্ষা করত লাইন ও বিভ্রাটের জন্য, ঘরের একটি রানার পুলে: একটি বিল্ড মেশিন যা চালু থাকা অবস্থায় প্রতিটি জব নেয়, আর সবসময় চালু একটি সার্ভারে স্ট্যান্ডবাই রানার, এমন একটি ওয়াচডগের পেছনে যা দ্বিধার সময় শিপিং চালু রাখার দিকেই ঝোঁকে। ইমেজ যায় একটি প্রাইভেট কনটেইনার রেজিস্ট্রিতে আর স্টুডিওর লাইব্রেরিগুলো একটি প্রাইভেট npm রেজিস্ট্রিতে, দুটোই ভবনের ভেতরে, আর প্রতিটি রান GitHub-এর রিটেনশনের পরেও আর্কাইভে থাকে। সবচেয়ে ধীর ডিপ্লয় আট মিনিট চব্বিশ সেকেন্ড থেকে নেমে এসেছে তিন মিনিট পাঁচ সেকেন্ডে, আর CI হয়েছে এক-তৃতীয়াংশ দ্রুত।

GitHub ActionsCI/CDDockerzotVerdaccioKubernetesGoSQLiteLinuxsystemd
Md Moniruzzaman Image

Md Moniruzzaman

পুরো গল্পটা

হোস্টেড পাইপলাইন একটি ব্যবসার কাছ থেকে অপেক্ষার মূল্য হিসেবে কী আদায় করে, আর বিল্ড, ইমেজ ও প্যাকেজ এক ছাদের নিচে আসার পর কী বদলাল।

পাইপলাইন ছিল অন্য কারও মেশিন, আর খারাপ দিনটাও অন্য কারও

২০২৬ সালের সেপ্টেম্বরের মাঝামাঝি পর্যন্ত প্রতিটি বিল্ড ও ডিপ্লয় চলত GitHub-এর হোস্টেড রানারে, আর হোস্টেড রানার মানে প্রতিবার একটি নতুন ভার্চুয়াল মেশিন: এক লাইনের পরিবর্তনের জন্যও বেস ইমেজ, প্রতিটি ডিপেনডেন্সি আর বিল্ডের প্রতিটি লেয়ার আবার ডাউনলোড হতো, তারপর ফেলে দেওয়া হতো। এরপর ইমেজটি তৈরি হতো সবসময় চালু প্রোডাকশন সার্ভারে, কারণ ফলাফল কেবল সেখানেই চলতে পারত, ফলে যে মেশিন ডেটাবেস আর পাবলিক সাইটগুলো চালাচ্ছিল, সে-ই তখন কম্পাইল করছিল। সবচেয়ে ধীর ডিপ্লয়ের মিডিয়ান ছিল আট মিনিট চব্বিশ সেকেন্ড, যার প্রায় পুরোটাই বিল্ড, মার্জগুলো একটার পেছনে আরেকটা লাইনে দাঁড়াত, আর কোনো ডিপেনডেন্সির ডাউনলোড টাইম আউট হলেই একটি রিলিজ ব্যর্থ হতে পারত, এমন ব্যর্থতা যার সঙ্গে কোডের কোনো সম্পর্ক নেই। রেকর্ডও টিকত না: GitHub ডিফল্টভাবে ওয়ার্কফ্লো লগ নব্বই দিন রাখে।

নিচের সার্ভিসটিরও নিজের একটা কঠিন বছর গেছে। ২ ফেব্রুয়ারি GitHub জানায় যে তাদের হোস্টেড রানার পাওয়া যাচ্ছিল না, আর জবগুলো লাইনে অপেক্ষা করতে করতে টাইম আউট হয়ে যায়: "Actions jobs queued and timed out while waiting to acquire a hosted runner" (ঘটনা)। ৫ মার্চ পঁচানব্বই শতাংশ ওয়ার্কফ্লো রান সময়মতো শুরু হয়নি: "failed to start within 5 minutes with an average delay of 30 minutes" (ঘটনা)। ৯ জুলাই প্রায় দশ ঘণ্টা ধরে জবগুলো দেরিতে শুরু হয় বা শুরুই হয়নি: Actions "experienced delayed and failed job starts on GitHub-hosted runners" (ঘটনা)। ২৬ আগস্ট জব শুরু হয়নি, "Actions jobs failed to start", আর তার পরের দুই ঘণ্টা রানগুলো পাঁচ মিনিটের বেশি দেরিতে শুরু হয়েছে: "were delayed starting by more than 5 minutes as the system caught up with delayed load" (ঘটনা)। ১৩ সেপ্টেম্বর GitHub জানায় Actions-সহ প্রায় ২৮টি সার্ভিসে প্রাপ্যতা কমে গিয়েছিল: "degraded availability across approximately 28 services, including Issues, Pull Requests, Actions" (ঘটনা)। তাদের স্ট্যাটাস পেজ থেকে গুনলে জানুয়ারি থেকে সেপ্টেম্বরের মধ্যে পঞ্চাশটির বেশি ঘটনা Actions-কে ছুঁয়েছে। রিপোজিটরি, রিভিউ আর ওয়ার্কফ্লোর সংজ্ঞাগুলো GitHub-এই থাকে; সরেছে শুধু সেই মেশিন যেখানে কাজটা চলে, আর সেই মেশিন যা কিছু ডাউনলোড করে ফেলে দিচ্ছিল তার সবটুকু।

ডিপ্লয় আটের জায়গায় তিন মিনিটে, মেপে দেখা

১৭ সেপ্টেম্বর হোস্টেড মিডিয়ানের সঙ্গে মেপে দেখা হয়: CMS-এর ডিপ্লয় ৮ মিনিট ২৪ সেকেন্ড থেকে নেমে ৩ মিনিট ০৫ সেকেন্ড, ওয়েবসাইটের ৬ মিনিট ১২ সেকেন্ড থেকে ২ মিনিট ২৭ সেকেন্ড, আর MCP সার্ভারের ১ মিনিট ৪৫ সেকেন্ড থেকে ৪৫ সেকেন্ড। একসঙ্গে মার্জ হওয়া দুটি রিলিজ ঘড়ির হিসাবে ৩ মিনিট ২২ সেকেন্ডে পৌঁছে যায়, আর তিনটি সার্ভিসের CI একসঙ্গে চালালে তা এক-তৃতীয়াংশ দ্রুত হয়।

Brand colour backdrop
Drawn chart of deploy and CI times on hosted runners against the home pool, measured on 17 September 2026: CMS deploy 8m24s to 3m05s, website deploy 6m12s to 2m27s, MCP server deploy 1m45s to 45s, website CI 3m06s to 2m04s, CMS CI 2m23s to 1m32s

প্রতিটি রান সেই মেশিনে, যে আগেরটি বানিয়েছিল

হোস্টেড রানার প্রতিবার একটি নতুন মেশিন। ঘরের পুল প্রতিটি জবে একই মেশিন, তাই তাদের ইমেজ লেয়ার আর প্যাকেজ ক্যাশ আগে থেকেই থাকে, ক্লাস্টারে যাওয়ার পথে ইমেজ কখনো ইন্টারনেট পার হয় না, আর বিল্ড চলে বিল্ডের জন্য তৈরি মেশিনে, সাইটগুলো চালানো মেশিনে নয়। একই বিল্ড ঠান্ডা ক্যাশ থেকে মাপা হয় ৫২৮ সেকেন্ড, আর গরম ক্যাশ থেকে ১৯২। ঘরের প্রথম রানগুলো তিন গুণ ধীর ছিল, যতক্ষণ না একটি ধাপ বাদ দেওয়া হয়: প্রতিটি বিল্ড তার ডিপেনডেন্সি ক্যাশ বাসার কানেকশন দিয়ে আবার GitHub-এ আপলোড করছিল, ওয়েবসাইটে তাতে যেত ৪১১ সেকেন্ড, যা অর্থবহ যখন রানারটি অন্য কারও মেশিন, আর একেবারেই নয় যখন ক্যাশ আগে থেকেই সেখানে থাকে যেখানে পরের বিল্ড চলবে।

Runs ভিউ নজরে রাখা প্রতিটি রিপোজিটরির প্রতিটি রান দেখায় এবং প্রতিটি রান শেষ হওয়া মাত্র আর্কাইভ করে রাখে, তাই তা GitHub-এর রিটেনশনের পরেও টিকে থাকে। স্ক্রিনশটের দিন সেখানে দেখা যাচ্ছিল ৪৯ সেকেন্ড, ৩ মিনিট ১৫ সেকেন্ড আর ২ মিনিট ৫১ সেকেন্ডের ডিপ্লয়, দুই থেকে তিন মিনিটের CI রান, আর ব্যর্থতাগুলোও চোখের সামনে ছিল: একটি ডিপ্লয়ের দুটি ব্যর্থ চেষ্টা, তারপর তৃতীয়টি, যা পাস করে।

Brand colour backdrop
The Runs view: the organisations watched with their request budgets, then the newest runs of every repository with status, title, branch, commit, runner, image and size, where it serves, duration and age, two failed attempts and a retry among them

একটি ডিপ্লয়, ধাপে ধাপে, নিজের সময়রেখায়

একটি রান খুললে প্রতিটি জব ও ধাপ দেখা যায় সেই রানের নিজস্ব সময়রেখায়, যা মাপা হয় GitHub-এর টাইমস্ট্যাম্প থেকে, পাশে থাকে রানটি যে ইমেজ পুশ করেছে তার digest, সাইজ ও প্ল্যাটফর্ম, আর সেই ইমেজ এখন কোথায় চলছে। পুনরায় চেষ্টাগুলো মুছে না দিয়ে রাখা হয়: স্ক্রিনশটের ডিপ্লয়টি প্রথম দুই চেষ্টায় ব্যর্থ হয়ে তৃতীয়টিতে পাস করে, প্রতিটি চেষ্টা আলাদাভাবে খোলে, আর দ্বিতীয়টিতে দেখা যায় ডিপ্লয় ধাপটি ছেচল্লিশ সেকেন্ড পর ব্যর্থ হচ্ছে, তাই সমাধানের পরও ব্যর্থতার কারণটি সেখানে থেকে যায়।

পাস করা চেষ্টাটি দেখায় ঘরের পুলে সময় কোথায় যায়: checkout আর ভার্সন বাড়াতে কয়েক সেকেন্ড, আর বিল্ড ও ক্লাস্টারে ডিপ্লয়ে আড়াই মিনিটের সামান্য কম। এটি আরও দেখায় এমন কিছু যা একটি কনসোল বলতে পারে কিন্তু CI-এর লগ পারে না: সেই ইমেজ আর রেজিস্ট্রিতে নেই, কারণ রিটেনশন শুধু সাম্প্রতিক বিল্ডগুলো রাখে, আর ক্লাস্টারে এখন আর কিছুই সেই digest চালাচ্ছে না।

Brand colour backdrop
A deploy's third attempt of three, passed: its image with digest, size and both platforms, no longer in the registry, nothing in the cluster running that digest, and every step on the run's time axis, the deploy to the home cluster taking most of it
The same deploy's second attempt: the deploy step failed in red after forty-six seconds, with Re-run failed jobs offered beside Re-run

বিল্ড মেশিন সরে গেলেও কাজ থেমে থাকে না

রানার পুলে একটি প্রাইমারি আর একটি স্ট্যান্ডবাই আছে। বিল্ড মেশিন চালু থাকলে তার রানাররা প্রতিটি জব নেয়, আর সবসময় চালু সার্ভারে থাকে স্ট্যান্ডবাই রানার, যা চালু হয় কেবল তখন, যখন একটি ওয়াচডগ সিদ্ধান্ত নেয় যে বিল্ড মেশিনটি আর নেই। মেশিনটিকে ডাউন ধরার আগে ওয়াচডগের দরকার একাধিক ব্যর্থ পরীক্ষা, আর ফিরে এসেছে ধরার আগে একাধিক সফল পরীক্ষা, তাই নেটওয়ার্কের ক্ষণিকের বিঘ্নে কিছুই এদিক-ওদিক দোলে না, আর হস্তান্তর দুই দিকেই দু-এক মিনিটের মধ্যে হয়ে যায়। এটি কখনো কোনো জবকে মাঝপথে কাটে না: বন্ধ হওয়ার আগে চলমান জবের জন্য অপেক্ষা করা হয়, আর স্ট্যান্ডবাই সরে দাঁড়ায় কেবল তখনই, যখন সে খালি।

ওয়াচডগ যদি GitHub-এ পৌঁছাতেই না পারে, তবুও সে স্ট্যান্ডবাই চালু করে দেয়, কারণ নজরদারির এমন ব্যর্থতা যা ডিপ্লয় থামিয়ে দেয়, তা যে বিভ্রাটের ওপর নজর রাখছিল তার চেয়েও খারাপ। কনসোলের ওভারভিউতে রানার পুল প্যানেল জানায় কোন দিক জবগুলো নিচ্ছে আর কোন স্ট্যান্ডবাই রানারগুলো প্রস্তুত।

Brand colour backdrop
Drawn failover: build machine runners take every job; a watchdog on the always-on server calls it down after more than one failed check and starts the standby, calls it back after more than one pass, and starts the standby anyway if it cannot reach GitHub
The runner pool panel: the build machine healthy and taking the jobs, and the standby runners listed as the fallback

ইমেজ আর প্যাকেজ, এক ছাদের নিচ থেকে

সবসময় চালু সার্ভারে একটি কনটেইনার রেজিস্ট্রি আর একটি npm রেজিস্ট্রি পাশাপাশি চলে, কারণ কনটেইনার ইমেজ আর npm প্যাকেজ এমন প্রোটোকলে কথা বলে যাদের মধ্যে কোনো মিল নেই। কনটেইনার রেজিস্ট্রি লোকাল নেটওয়ার্কে পুলের বানানো প্রতিটি ইমেজ নেয়: পুশ করতে পারে শুধু একটি অ্যাকাউন্ট, যা কিছু টেনে নেয় তার জন্য রিড-অনলি অ্যাকাউন্ট, কোনো বেনামি প্রবেশাধিকার নেই, আর একটি ট্যাগ দুটি প্রসেসর আর্কিটেকচারই বহন করতে পারে, যাতে প্রতিটি নোড নিজের সঙ্গে মেলে এমন বিল্ড টেনে নেয়। রিটেনশন প্রতিটি সার্ভিসের সবচেয়ে সাম্প্রতিক দুটি বিল্ড আর সবশেষে টানা বিল্ডটি রাখে, আর এটাই রোলব্যাকের সুযোগ, যা ধরে নেওয়া হয় না, স্পষ্ট করে বলা থাকে।

npm রেজিস্ট্রি স্টুডিওর নিজস্ব লাইব্রেরি পরিবারকে পরিবেশন করে। প্রতিটি লাইব্রেরির রিলিজ তার GitHub Release থেকে বাইট-বাই-বাইট সেখানে প্রকাশিত হয়, ক্লাস্টারের ভেতরের একটি সিঙ্কের মাধ্যমে প্রতি পাঁচ মিনিটে, প্রতিটি রিডের জন্য লগইন লাগে, পাবলিক নামে লেখা প্রত্যাখ্যাত হয়, আর রাতের একটি জব প্রতিটি প্রকাশিত ভার্সনকে তার রিলিজের সঙ্গে মিলিয়ে দেখে। কোনো রেজিস্ট্রিরই নিজস্ব ইন্টারফেস নেই, তাই কনসোলই তাদের পর্দা: Estate ভিউ কনটেইনার রেজিস্ট্রির রিপোজিটরিগুলো তাদের সাইজ ও প্ল্যাটফর্মসহ দেখায়, আর এই লাইব্রেরি ব্যবহার করা যেকোনো প্রজেক্টে ইনস্টল ভবনের ভেতর থেকেই মিটে যায়।

Brand colour backdrop
The estate view's Registry tab, the container registry as the console's read-only user sees it: its image repositories with newest tag and digest, size, the amd64 and arm64 platforms of the multi-architecture ones, and tags kept against those let go
A terminal in a consumer project: its .npmrc points the gm-libs scope at the private registry, and npm install fetches the studio's libraries from it in milliseconds while public packages still come from npmjs

একটি মার্জ থেকে চলমান পড পর্যন্ত, আর ফেরার একটি লাইন

একটি মার্জ পুলে বিল্ডকে লাইনে দাঁড় করায়, ইমেজ লোকাল নেটওয়ার্কে রেজিস্ট্রিতে যায়, আর ডিপ্লয় চলে এমন একটি পরিচয়ে যা একটি namespace-এ সীমাবদ্ধ, যার মুছে ফেলার অধিকার নেই এবং যার আছে একটিমাত্র নির্দিষ্ট secret। প্রতিটি নোড নিজের সঙ্গে মেলে এমন বিল্ড টেনে নেয়, আর প্রতিটি রিপোজিটরির একটি ভেরিয়েবল কোনো সার্ভিসকে তার পরের push-এ হোস্টেড রানারে ফেরত পাঠায়।

Brand colour backdrop
Drawn path from a merge to a running pod: the runner pool, one image for both architectures, the private registry over the local network, a deploy identity scoped to one namespace, each node pulling its build, and one variable back to hosted runners
A deploy's image and where it runs: the website's image in the registry with both platforms, served by one copy on each node

কাজের সপ্তাহে এর প্রভাব, আর এটা কাদের জন্য

মার্জগুলো আর একে অপরের জন্য অপেক্ষা করে না: বিল্ড মেশিন চালু থাকলে রিলিজগুলো পাশাপাশি বিল্ড ও ডিপ্লয় হয়, আর স্ট্যান্ডবাইতে একটি লক ভারী ধাপগুলো একে একে চালায়, যাতে কিছু ধাক্কা না খায়। একটি সমাধান আটের বদলে প্রায় তিন মিনিটে বেরিয়ে যায়, সবসময় চালু সার্ভার কম্পাইল করে কেবল তখন, যখন বিল্ড মেশিন নেই, আর GitHub মুছে ফেলার পরেও প্রতিটি রানের রেকর্ড ভবনের ভেতরেই থেকে যায়। রিপোজিটরি, রিভিউ আর ওয়ার্কফ্লোর সংজ্ঞা সবই GitHub-এ রয়ে গেছে; সরেছে কেবল মেশিন, ক্যাশ, ইমেজ আর প্যাকেজ।

সীমাবদ্ধতাটা শুরুতেই বলে রাখা হয়: বিল্ডের মাঝপথে বিদ্যুৎ চলে গেলে সেই বিল্ড ব্যর্থ হয়, আর সেটি আবার চালানো হয়। যে দলের রিলিজ লাইনে দাঁড়াতে শুরু করেছে, যাদের কোড আর ইমেজ ভবনের বাইরে যাওয়া উচিত নয়, আর যে প্রতিষ্ঠাতা কোনো সমাধানকে অন্যের লাইনে আটকে থাকতে দেখেছেন, তাদের জন্য এটি সঠিক পদক্ষেপ। মেশিনগুলোর দায়িত্ব নেওয়ার কেউ নেই এমন দলের জন্য এটি ভুল পদক্ষেপ, আর সেটা সোজাসুজি বলা দরকার। নিচের ক্লাস্টারটি একটি নোডের ক্লাস্টার হয়ে ওঠার গল্প, তাকে ঘিরে থাকা প্ল্যাটফর্মটি স্টুডিও চালানো হোমল্যাব, আর একই পদ্ধতি একটি ক্লায়েন্টের প্ল্যাটফর্মে প্রয়োগ হলে তা হয় সেলফ-হোস্টেড Kubernetes-এ ডাউনটাইম ছাড়া মাইগ্রেশন।

আপনার আরও ভালো লাগতে পারে

27 Pearls App Logo

27 Pearls - মোবাইল রিলিজ এবং স্টোর সাবমিশন

একটি তৈরি 27 Pearls অ্যাপ এক সপ্তাহের এনগেজমেন্টের মধ্যেই App Store ও Google Play-তে অনুমোদিত লিস্টিং হয়ে ওঠে, কোনো দফায় প্রত্যাখ্যান ছাড়াই। সেই সপ্তাহে ছিল রিলিজ বিল্ড ও সাইনিং, শিক্ষার্থীর সুবিধা ঘিরে লেখা লিস্টিংয়ের কপি, প্রয়োজনীয় প্রতিটি ডিভাইস সাইজের স্ক্রিনশট, অ্যাপ যা সংগ্রহ করে তার সঙ্গে মিলিয়ে প্রাইভেসি ঘোষণা, আর রিভিউয়ারের জন্য কাজ করা একটি অ্যাকাউন্ট। অ্যাপটি আজও Google Play-তে আছে।

Md Moniruzzaman Image

Md Moniruzzaman

মে 05, 2023

Dr. Kris Valenza
fully booked brand logo

Fully Booked - শূন্য ডাউনটাইমে সেলফ হোস্টেড কুবারনেটিসে মাইগ্রেশন

Fully Booked চলত ম্যানেজড ক্লাউড অবকাঠামোয়, যার বিল প্রতি মাসে বাড়ত আর পুরো স্ট্যাকের মালিকানা কারও হাতে ছিল না। আমরা পুরো প্ল্যাটফর্মটি সেলফ হোস্টেড কুবারনেটিস ক্লাস্টারে সরিয়ে এনেছি, ব্যবহারকারীদের জন্য এক মিনিটও ডাউনটাইম ছাড়া। কাটওভারে ছিল DNS, ইনগ্রেস, ডেটাবেস এবং রিলিজ পাইপলাইন, এমনভাবে সাজানো যে প্রতিটি স্তর নতুন ক্লাস্টারে প্রমাণিত হওয়ার পরেই ট্রাফিক সরানো হয়েছে। সেই সপ্তাহে অ্যাপ ব্যবহারকারী কেউ টের পাননি কিছু ঘটেছে, আর সেটাই ছিল উদ্দেশ্য। মাসিক বিল হয়ে গেল নিজস্ব হার্ডওয়্যার, এবং এখন সেই ক্লাস্টারই প্ল্যাটফর্মের সাপ্তাহিক রিলিজ বহন করে।

Md Moniruzzaman Image

Md Moniruzzaman

জুন 23, 2026

+1
Dominic Dormer
Webanion brand logo

একটি নোড হলো ক্লাস্টার, অথচ কোনো অ্যাপ্লিকেশন বদলাতে হয়নি

যেকোনো মুহূর্তে বন্ধ হতে পারে এমন একটি দ্বিতীয় মেশিন কোনো অ্যাপ্লিকেশন না বদলেই চলমান একটি এক-নোডের ক্লাস্টারে যোগ দিয়েছে। সবসময় চালু থাকা একটি সার্ভার রাখে কন্ট্রোল প্লেন, প্রতিটি ডেটাবেস ও ভলিউম আর প্রতিটি সার্ভিসের প্রথম কপি; বিল্ড মেশিন একটি taint-এর আড়ালে বিল্ড আর স্টেটলেস সার্ভিসের দ্বিতীয় কপিগুলো নেয়, আর সেটি ঘুমিয়ে থাকলে সেই কপিগুলো ফিরে না গিয়ে অপেক্ষা করে। কাজ ফুরোলে সেটি নিজেই বন্ধ হয় আর কোনো জব সারিতে এলে ফিরে আসে, একটি কনসোল প্রতিটি নোড, ওয়ার্কলোড আর উপস্থিতির সময়সীমা দেখায়, আর সবসময় চালু সার্ভারের প্রতিটি CPU request মাপা হয়েছে, যাতে তার রিজার্ভেশন বরাদ্দযোগ্য সক্ষমতার ৮৪ থেকে ৫৬ শতাংশে নেমে এসেছে।

Md Moniruzzaman Image

Md Moniruzzaman

সেপ্ট 22, 2026

Read the Md Moniruzzaman blog

ব্লগটি প্রোডাকশনের ময়দান থেকে লেখা নোট: আর্কিটেকচারের সিদ্ধান্ত, বাস্তব ব্যবহারকারীর মুখোমুখি টিকে যাওয়া AI সিস্টেম, আর নিজের খরচ নিজে তোলা অবকাঠামো। কাজ থেকে লেখা, কাজ নিয়ে গল্প নয়।