প্রথমবার Deploy করা
— ধাপে ধাপে
Vite + React frontend আর Express server (bundled হয়ে dist/server.cjs হিসেবে চলে) —
এই গাইড অনুসরণ করে cPanel এর Node.js Selector দিয়ে প্রথমবার লাইভ করুন। নিচে একটা recurring
সমস্যার সমাধানও দেওয়া আছে, যা msh.ebsoftbd.com ও hms.ebsoftbd.com
দুটো app এই দেখা গিয়েছিল।
Zip আপলোড ও Extract
cPanel File Manager দিয়ে project zip আপলোড করুন ~/msh.ebsoftbd.com ফোল্ডারে —
যেখানে Application Root সেট করা আছে সেই একই জায়গায়। আপলোড শেষে zip ফাইলে right-click করে
Extract করুন।
Terminal খুলে Virtualenv Activate করুন
cPanel Terminal খুলুন। Setup Node.js App পেজে আপনার app এর এন্ট্রিতে যে কমান্ডটা দেওয়া থাকে, সেটা কপি করে পেস্ট করুন — এটা সঠিক Node ভার্সন ও virtualenv লোড করে দেয়।
source /home/ebsoftbd/nodevenv/msh.ebsoftbd.com/20/bin/activate && cd /home/ebsoftbd/msh.ebsoftbd.com
Dependencies Install করুন
--legacy-peer-deps ফ্ল্যাগটা দরকার, কারণ একটা test-only dependency
(@firebase/rules-unit-testing) firebase v12 আশা করে যেখানে প্রজেক্ট firebase v11
ব্যবহার করে। এটা শুধু peer-dependency ওয়ার্নিং, production build-এ প্রভাব ফেলে না।
npm install --legacy-peer-deps
Production Build চালান
একটা কমান্ডে দুটো কাজ হয়: Vite দিয়ে frontend বান্ডেল হয়, আর esbuild দিয়ে
server.ts কম্পাইল হয়ে dist/server.cjs তৈরি হয় — এটাই প্রোডাকশনে চলবে।
npm run build
Startup File নিশ্চিত করুন
cPanel → Setup Node.js App → আপনার app এ ক্লিক করুন। দুটো ফিল্ড চেক করুন:
Application startup file → dist/server.cjs Application mode → Production
SAVE করুন
SAVE বাটনে ক্লিক করুন — এমনকি কিছু পরিবর্তন না করলেও। এটা cPanel কে
.htaccess ফাইলে সঠিক Passenger routing directive লিখে দিতে বাধ্য করে, যেটা ছাড়া
Apache/LiteSpeed request গুলো Node app পর্যন্ত পাঠাতে পারে না।
RESTART করুন
একই পেজে RESTART বাটনে ক্লিক করুন। এটা Node process পুনরায় চালু করে নতুন build ও environment variables লোড করবে।
Live Site চেক করুন
ব্রাউজারে msh.ebsoftbd.com খুলে hard refresh
করুন (Ctrl+Shift+R) — সাধারণ refresh এ পুরনো cache থেকে যেতে পারে। কোনো error দেখলে cPanel
Node.js App পেজে Logs চেক করুন, বা browser এ F12 চেপে Console দেখুন।
সাইট লোড হচ্ছে না? — Blank Page + "application/octet-stream" Error
উপরের সব ধাপ ঠিকমতো করার পরও যদি সাইট blank দেখায় এবং browser console এ এই error আসে:
Console এ কী দেখাচ্ছে চেক করুন
F12 চেপে Console ট্যাবে গিয়ে দেখুন এরকম error আছে কিনা:
Failed to load module script: Expected a JavaScript-or-Wasm module script
but the server responded with a MIME type of "application/octet-stream"
/src/main.tsx ফাইলটা raw/অপরিবর্তিত অবস্থায় পাচ্ছে —
অর্থাৎ built dist/index.html এর বদলে project root এর কাঁচা (dev) index.html
সরাসরি সার্ভ হচ্ছে, Node app পর্যন্ত request পৌঁছাচ্ছেই না।
.htaccess চেক করুন
Terminal এ গিয়ে (নিচে <domain> এর জায়গায় আপনার আসল domain বসান, যেমন
hms.ebsoftbd.com বা msh.ebsoftbd.com):
cat ~/<domain>/.htaccess
SetEnv লাইনগুলো (environment variables) আর PHP handler ব্লক থাকে —
কিন্তু PassengerAppRoot, PassengerStartupFile এই ধরনের লাইন
না থাকে — সেটাই আসল সমস্যা। এই লাইন ছাড়া Apache/LiteSpeed কখনো request Node app এ
পাঠাবে না, নিজে থেকেই static file সার্ভ করে দেবে।
Passenger Directive রিজেনারেট করুন
cPanel → Setup Node.js App → আপনার app এ ক্লিক করুন। কিছু
পরিবর্তন না করেও SAVE বাটনে ক্লিক করুন — এটা cPanel কে বাধ্য
করবে .htaccess এ সঠিক Passenger ব্লক আবার লিখে দিতে:
# DO NOT REMOVE. CLOUDLINUX PASSENGER CONFIGURATION BEGIN PassengerAppRoot "/home/ebsoftbd/<domain>" PassengerBaseURI "/" PassengerNodejs "/home/ebsoftbd/nodevenv/<domain>/20/bin/node" PassengerAppType node PassengerStartupFile dist/server.cjs # DO NOT REMOVE. CLOUDLINUX PASSENGER CONFIGURATION END
Root এ Raw index.html থাকলে সরান
এই সার্ভারে Application Root ও Document Root একই ফোল্ডার হওয়ায়, যদি project root এ raw
(dev-mode) index.html ফাইলটা থেকে যায়, তাহলে Passenger config ঠিক থাকলেও Apache
সেই physical ফাইলটাই সরাসরি সার্ভ করে দেবে, কখনো dist/index.html পর্যন্ত পৌঁছাবে
না। build হওয়ার পর সবসময় এটা সরিয়ে দিন:
cd ~/<domain> ls index.html 2>/dev/null && mv index.html index.source.html
mv index.source.html index.html দিয়ে আবার ফেরত আনতে
হবে — নাহলে npm run build ফেল করবে (vite index.html খুঁজে পাবে না)।
Restart করে চেক করুন
cPanel → Setup Node.js App → RESTART। তারপর সাইট hard refresh করুন (Ctrl+Shift+R) — সাধারণ refresh এ পুরনো cache থেকে যেতে পারে।
Static Asset (CSS) ও PHP Handler নিয়ে জেনে রাখা ভালো
এই দুটো সরাসরি "সমস্যা" না, কিন্তু বিভ্রান্তি তৈরি করতে পারে — তাই আলাদা করে ব্যাখ্যা করা হলো।
Build এর পর CSS/Styling মিসিং দেখাচ্ছে
Site লোড হচ্ছে, JS ও কাজ করছে, কিন্তু পুরো পেজ unstyled/plain HTML এর মতো দেখাচ্ছে। Vite প্রতিটা
build এ CSS/JS ফাইলের নামে নতুন hash যোগ করে (যেমন index-8P2N.css →
index-Qk91.css), তাই এটা সাধারণত দুটো কারণে হয়:
ls -la dist/assets/*.css grep -o 'assets/index-[a-zA-Z0-9]*\.css' dist/index.html
দুটো কমান্ডের আউটপুটে ফাইলের নাম (hash সহ) মিলছে কিনা দেখুন। না মিললে বুঝবেন পুরোনো build এখনো
সার্ভ হচ্ছে অথবা browser পুরোনো index.html cache করে রেখেছে।
npm run build আবার ঠিকভাবে চালানো হয়েছে কিনা নিশ্চিত করুন, (২) browser এ
hard refresh (Ctrl+Shift+R) করুন, (৩) মোবাইলে দেখলে ব্রাউজারের cache/site data আলাদাভাবে clear
করতে হতে পারে।
.htaccess এ PHP Handler ব্লক দেখে চিন্তার কিছু নেই
.htaccess ফাইলে Passenger config এর নিচে cPanel নিজে থেকেই এই ব্লকটা যোগ করে:
# php -- BEGIN cPanel-generated handler, do not edit # Set the "ea-php81" package as the default "PHP" programming language. <IfModule mime_module> AddHandler application/x-httpd-ea-php81 .php .php8 .phtml </IfModule> # php -- END cPanel-generated handler, do not edit
এটা শুধু .php/.php8/.phtml এক্সটেনশনের ফাইলের জন্য প্রযোজ্য —
আপনার Vite/React/Express অ্যাপের কোনো ফাইলে এই এক্সটেনশন নেই, তাই এটা Node app এর সাথে কখনো
সংঘর্ষ করে না।
.htaccess এ PHP এর কথা লেখা আছে কেন — এটা normal, প্রতিটা cPanel domain
এর .htaccess এ এটা থাকে।
Deploy সম্পূর্ণ
সাইট লোড হলে deployment সফল। ৯–১৩ নম্বর ধাপ Passenger routing সমস্যার জন্য, আর ১৪–১৫ নম্বর ধাপ CSS/asset এবং PHP handler সংক্রান্ত বিভ্রান্তি দূর করার জন্য — যেকোনো নতুন domain/app এ কাজে লাগবে।