নিজের সার্ভারে ডিপ্লয় করার মানে হলো একটা এজেন্টকে এমন একটা বক্সে SSH-সদৃশ অ্যাক্সেস দেওয়া যার জন্য আপনি টাকা দিচ্ছেন, যাতে হয়তো আগে থেকেই অন্য কিছু থাকতে পারে। এটা একটা ফ্রি সাবডোমেইনে পাবলিশ করার চেয়ে ভিন্ন স্তরের বিশ্বাস, আর সেটাপও সেটাই প্রতিফলিত করে — কয়েকটা ফিল্ড, একবার পূরণ করা হয়, তারপর প্রতিটা বিল্ড শুধু একটা বাটন। এখানে মানুষ আসলে কী জিজ্ঞেস করে একটা সেটআপ করার আগে ও পরে তা দেওয়া হলো।
একটা টার্গেট তৈরি করতে আমার কী দরকার?
পাঁচটা জিনিস, Settings → Deploy-তে:
- একটা নাম যা পরে চিনতে পারবেন — "prod-vps", "client-hostgator", রাত ১১টায় একটা ড্রপডাউনে যেটা টিকে থাকে
- হোস্ট এবং পোর্ট
- SFTP ক্রেডেনশিয়াল
- একটা ওয়েবরুট পাথ
কোনো API টোকেন নেই, সার্ভারে ইনস্টল করার মতো কোনো CLI নেই, নজরদারির জন্য কোনো cron job নেই। আপনার হোস্ট যদি SFTP অ্যাক্সেস দেয় — যা প্রায় প্রতিটি শেয়ার্ড হোস্ট, প্রতিটি VPS, প্রতিটি ম্যানেজড ওয়ার্ডপ্রেস বক্সকে কভার করে — তাহলে প্রায় দুই মিনিটে আপনার কাজ শেষ।
পাসওয়ার্ড না কী?
আপনার হোস্ট সাপোর্ট করলে, কী ব্যবহার করুন। পাসওয়ার্ড ঠিকই কাজ করে এবং আমরা সেগুলো আপনার অ্যাকাউন্টের সাথে স্কোপ করে সংরক্ষণ করি, কিন্তু কী মানে একটা কম গোপনীয় তথ্য কোথাও পড়ে থাকা — পরে কিছু ভুল হলে "একটা কী রিভোক করা" আর "যে পাসওয়ার্ডটা অন্য কোথাও রিইউজ হয়ে গেছে সেটা সবখানে রিসেট করা"র মধ্যে পার্থক্য। অনেক সস্তা শেয়ার্ড-হোস্টিং SFTP সেটআপ শুধু পাসওয়ার্ড অথ অফার করে, সেটাও ঠিক আছে। শুধু সেই পাসওয়ার্ড অন্য কোথাও রিইউজ করবেন না।
সঠিক ওয়েবরুট পাথ কীভাবে খুঁজে পাবো?
এই ফিল্ডে মানুষ প্রথমবার ভুল করে, কারণ ভুল উত্তরটাও বিশ্বাসযোগ্য দেখায়। এটা আপনার হোম ডিরেক্টরি নয়, এটা /var/www — এটা সেই নির্দিষ্ট ফোল্ডার যেখান থেকে আপনার ওয়েব সার্ভার পরিবেশন করার জন্য কনফিগার করা।
| সার্ভার | সাধারণ ওয়েবরুট |
|---|---|
| Apache / cPanel | public_html |
| Nginx | /var/www/mysite/html — বা তিন বছর আগে কোনো ডেভেলপার এমন কারণে নাম দেওয়া একটা পাথ যা এখন কারও মনে নেই |
যদি নিশ্চিত না হন, একটা ফেলে দেওয়ার মতো ফাইল রেখে দিন test.txt আপনি যেই ফোল্ডারটা সঠিক মনে করেন সেখানে যেকোনো SFTP ক্লায়েন্ট ব্যবহার করে, তারপর দেখুন এটা লোড হয় কিনা yoursite.com/test.txt। এটা ভুল করলে ডিপ্লয় তখনও সফলতার রিপোর্ট দেবে — এজেন্ট বিশ্বস্তভাবে ভুল ফোল্ডারে ফাইল লিখে দেয়, আর আপনি একটা লাইভ সাইটের দিকে তাকিয়ে থাকেন যেটা পরিবর্তন হয়নি, ভাবতে থাকেন কেন।
একটা টার্গেট কি একাধিক ডোমেইন কভার করতে পারে?
হ্যাঁ, আর এই অংশটাই প্রথম সাইট পার হওয়ার পর সত্যিকারের সময় বাঁচায়। একটা টার্গেট মানে একটা সার্ভার এবং একসেট ক্রেডেনশিয়াল — এটা কোনো একক ডোমেইনের সাথে বাঁধা নয়। Domain Management-এ আপনি প্রতিটা ডোমেইনকে একটা টার্গেটের সাথে যুক্ত করেন, নিজস্ব ওয়েবরুট ওভাররাইড সহ। একটা VPS-এ Nginx সার্ভার ব্লক দিয়ে তিনটা সাইট চালাচ্ছেন?
site-a→/var/www/site-asite-b→/var/www/site-bsite-c→/var/www/site-c
একটা টার্গেট, তিনটা অ্যাটাচমেন্ট। আপনি একটা SSH পাসওয়ার্ড তিনবার নতুন করে দিচ্ছেন না, আর তিনটা প্রায়-একরকম টার্গেট রক্ষণাবেক্ষণও করছেন না যেগুলো একটা কী রোটেট করার দিন একটাকে ভুলে গেলে সিঙ্ক থেকে সরে যায়। তিনটা ডোমেইনের যে কোনোটাতে ডিপ্লয় ক্লিক করুন, এটা ইতিমধ্যে জানে কোন সার্ভার এবং কোন ফোল্ডার — ডিপ্লয়ের সময় আপনাকে বেছে নিতে হয় না।
কানেক্ট করার সময় এজেন্ট আসলে কী করে?
প্রথমে, এটা চারপাশে তাকায় — শুধু-পড়ার জন্য, এখনও কিছু লেখা হয় না। এই ইন্সপেকশন চেক করে:
- একটা খালি ফোল্ডার
- এই ঠিক বিল্ডের একটা আগের ভার্সন
- একটা পুরনো ওয়ার্ডপ্রেস ইনস্টল
- আপনার হোস্ট ডিফল্টভাবে সেখানে রেখে দেওয়া একটা "কামিং সুন" প্লেসহোল্ডার
এটাই কৌশল ঠিক করে। একটা খালি ওয়েবরুট সরাসরি আপলোড পায়। ইতিমধ্যে কিছু থাকা একটা ওয়েবরুট আরও সাবধানে হ্যান্ডল করা হয়, কারণ অনেক বাস্তব সেটআপে সাইটের পাশাপাশি জিনিস থাকে যা হারিয়ে যাওয়া উচিত নয়:
- A
.well-knownSSL ভ্যালিডেশনের জন্য ফোল্ডার - একটি
uploadsযে ডিরেক্টরি কেউ git-এ রাখেনি - A
wp-config.phpযা কেউ স্পর্শ করতে চায় না
এখানে কাজটা "মুছে ফেলে প্রতিস্থাপন" এর চেয়ে বেশি "কী পরিবর্তন হয়েছে বের করে মিলিয়ে নেওয়া"র কাছাকাছি।
তারপর, একটা বাইটও ওভাররাইট হওয়ার আগে, বিদ্যমান ওয়েবরুট আপনার নিজের হোস্টে একটা ভার্সন হিসেবে ক্যাপচার করা হয়। কোনো ডেটাবেস রেকর্ড নয়, আমরা হিসাব করে সঠিক বলে আশা করা কোনো ডিফ নয় — সেখানে যা ছিল তার প্রকৃত একটা স্ন্যাপশট। এটা যেকোনো টার্গেটে প্রথম ডিপ্লয়ে সবচেয়ে বেশি গুরুত্বপূর্ণ, কারণ সেই ডিপ্লয় সবসময় কোনো কিছুর উপরে বসে, এমনকি সেই কিছুটা কিছুই না হলেও। খালি ফোল্ডার, খালি স্ন্যাপশট। পাঁচ বছর আগের স্ট্যাটিক সাইট যা তৈরি করার কথা কেউ মনে রাখে না — স্পর্শ করার আগেই, ঠিক যেমনটা ছিল, বিনামূল্যে সংরক্ষিত। সেই প্রথম ডিপ্লয়টাই সেই ডিপ্লয় যা নিয়ে আপনি সবচেয়ে কম নিশ্চিত, তাই এটাই সেই জায়গা যেখানে এটা সবচেয়ে বেশি গুরুত্বপূর্ণ।
এটা কি আমার সোর্স কোড আপলোড করে নাকি বিল্ড করা সাইট?
সবসময় বিল্ট সাইট। একটি স্ট্যাটিক সাইটের জন্য এটি জেনারেট করা পেজগুলো। ফ্রেমওয়ার্ক বিল্ডের ক্ষেত্রে — Next.js, Vite, সাইটের ধরন যা-ই চাক না কেন — এটি কম্পাইল করা আউটপুট, অর্থাৎ dist অথবা build ফোল্ডার, কখনোই সোর্স ট্রি নয়। আমি মনে করি এটাই সঠিক সিদ্ধান্ত, যদিও এর মানে হলো আপনি SSH করে ঢুকে npm run dev চালাতে পারবেন না সার্ভারে যা আছে তার বিপরীতে। সোর্স আপলোড করার মানে হলো আপনার প্রোডাকশন ওয়েবরুটে শুধু HTML সার্ভ করার জন্যও একটি Node রানটাইম এবং বিল্ড টুলচেইন প্রয়োজন হবে — অর্থাৎ যে শেয়ার্ড হোস্টিং বক্স কখনো বিল্ড পাইপলাইন চালানোর জন্য বানানো হয়নি, সেটাকে সেই কাজে রূপান্তরিত করা, এবং প্রতিটি ডিপ্লয়কে পরিণত করা "আশা করি সার্ভারে যথেষ্ট মেমোরি আছে যাতে npm install শেষ হয়।" শুধু কম্পাইল করা আউটপুট পাঠানো ওয়েবরুটকে ঠিক তেমনই রাখে যেমনটা একটি স্ট্যাটিক ফাইল সার্ভার আশা করে। নিরস। আর নিরসই যা আপনি চান রাত ২টায় যখন কিছু একটা ভুল হয়ে গেছে এবং আপনি সেই ফোল্ডারের দিকে তাকিয়ে বোঝার চেষ্টা করছেন আসলে কী সার্ভ করা হচ্ছে।
একটা ডিপ্লয় আসলে কাজ করেছে কিনা তা কীভাবে বুঝব?
আপলোডের পর, এজেন্ট লাইভ URL-এ গিয়ে চেক করে দেখে সেটি রিজলভ হচ্ছে কিনা — কোনো 500 নয়, কোনো ফাঁকা পেজ নয়। এজেন্ট যা খুঁজে পায়, এবং পরিদর্শনের সময় যা লক্ষ্য করে যার ব্যাপারে আপনার মতামত চায় ("এই ওয়েবরুটে একটি wp-content ফোল্ডার আছে যা আমি অপরিবর্তিত রেখেছি, নিশ্চিত করুন এটাই প্রত্যাশিত কিনা"), সবকিছু বিল্ডের চ্যাট থ্রেডে চলে যায়। পুরো প্ল্যাটফর্ম জুড়ে এটাই প্যাটার্ন: নীরব সফলতা নয়, নীরব ব্যর্থতা থেকে সাপোর্ট টিকিটে পরিণত হওয়া নয়। এজেন্ট আপনাকে বলে দেয় সে কী দেখেছে এবং কী সিদ্ধান্ত নিয়েছে, ঠিক একই থ্রেডে যেখানে আপনি বিল্ড চেয়েছিলেন।
ভার্সন হিস্ট্রিতে আসলে কী থাকে?
প্রতিটা ডিপ্লয় একটা ভার্সন যোগ করে — শুধু প্রথমটা নয়। তাই হিস্ট্রিটা কোনো বিমূর্ত টাইমলাইনের বিপরীতে প্লট করা আপনার বিল্ডগুলো নয়; এটা সেই ওয়েবরুট থেকে যা পরিবেশন করা হয়েছিল তার আক্ষরিক ক্রম, ক্রমানুসারে, আপনার আসার আগে যা কিছু ছিল তা থেকে শুরু করে। ভার্সন ওয়ান সবসময় সেই প্ল্যাটফর্ম-পূর্ব অবস্থা, স্বয়ংক্রিয়ভাবে ক্যাপচার করা। আপনাকে এটা নিয়ে ভাবতে হবে না।
রিভার্ট আসলে কী পুনরুদ্ধার করে?
আগের লাইভ ভার্সন, ঠিক যেমন ছিল — কোনো পুরনো বিল্ডের পুনরায়-রান নয়, কোনো আনুমানিক ভার্সন নয়। আপনার সামনে ট্র্যাফিক পরিবেশন করা আসল ফাইলগুলো। এটা আমি অন্য কোথাও ব্যবহার করা বেশিরভাগ "রোলব্যাক" ফিচারের চেয়ে উল্লেখযোগ্যভাবে শক্তিশালী একটা গ্যারান্টি, যেগুলো সাধারণত মানে "একটা পুরনো কমিট থেকে পুনরায়-ডিপ্লয়" এবং চুপচাপ ধরে নেয় যে আপনার বিল্ড প্রসেস নির্ণায়ক এবং আপনার এনভায়রনমেন্ট তখন থেকে পরিবর্তন হয়নি। এখানে রিভার্ট একটা জানা-ভালো স্ন্যাপশটের একটা পুনরুদ্ধার, তাই চাপের মধ্যে এটা ব্যবহার করা নিরাপদ — আপনাকে ভাবতে হয় না রোলব্যাক যে জিনিসটা রোলব্যাক করছে তার চেয়ে ভিন্নভাবে আচরণ করবে কিনা।
আর যে মুহূর্তে আপনার আসলে এটার দরকার হয় সেটা কখনোই শান্ত মুহূর্ত হয় না; এটা হয় "নতুন বিল্ড চেকআউট ভেঙে দিয়েছে আর ট্র্যাফিক এখনই লাইভ চলছে"।
এক ক্লিক, আগের ভার্সন পুনরুদ্ধার, শেষ। এটাকে পরে-ভাবা নয় বরং একটা প্রথম-শ্রেণীর ফিচার হিসেবে ট্রিট করার পেছনের যুক্তি আছে ভয় ছাড়াই ইটারেট করা-তে — দরকার হওয়ার আগে একবার পড়ে নেওয়ার মতো। হিস্ট্রি এবং রিস্টোর কন্ট্রোল দুটোই বিল্ড কার্ডে এবং টার্গেটের নিজস্ব হিস্ট্রি ভিউতে থাকে।
এটা কি আমার ডেটাবেসও ব্যাকআপ করে?
না, আর আমি সরাসরি এটা বলতে চাই, কাউকে অন্যরকম ধরে নিতে না দিয়ে। হোস্টে ভার্সন হিস্ট্রি শুধু এই ডিপ্লয় পাইপলাইন ওয়েবরুটে যা রেখেছে তা কভার করে। আপনার সাইটে যদি একটা ডেটাবেস থাকে, বা ব্যবহারকারীর আপলোড, বা ডিপ্লয়ের বাইরে পরিবর্তনশীল অন্য কিছু থাকে, সেটা সম্পূর্ণ আলাদা একটা বিষয়ে — রিভার্ট সেটা স্পর্শ করে না এবং এটাকে সেসব কভার করা একটা ব্যাকআপ স্ট্র্যাটেজি বলে ভুল করা উচিত নয়।



