সরাসরি পর্বে যান
পর্ব ৫৩ · ৫৯-এর মধ্যে · মডিউল ৭

Git, GitHub আর ওয়েবসাইট প্রকাশ — GitHub Pages, Netlify আর cPanel

Git, GitHub & Going Live — GitHub Pages, Netlify, Vercel, Cloudflare Pages and cPanel

Taught in Bangla, this lesson explains why version control matters and the working directory, staging area and repository, daily Git commands from init to merge, good commit messages, .gitignore and keeping secrets out, branches, pushing to GitHub over HTTPS or SSH, publishing with GitHub Pages, Netlify, Vercel, Cloudflare Pages or cPanel and SFTP, custom domains, DNS, HTTPS and a pre-launch checklist.

এই পর্বে যা শিখবেন

  • Git কেন দরকার, আর working directory, staging area ও repository — তিন জায়গার খেলা
  • প্রতিদিনের কমান্ড: init, status, add, commit, log, diff, switch, merge — আর ভালো commit message
  • GitHub-এ repository বানিয়ে push করা, HTTPS বনাম SSH, আর গোপন তথ্য বাঁচানো
  • GitHub Pages, Netlify/Vercel/Cloudflare Pages আর cPanel/SFTP — কোনটি কখন
  • domain, DNS, HTTPS আর প্রকাশের আগের পেশাদার চেকলিস্ট

১ · “final_final2.html” সমস্যা — কেন version control

সাবরিনা একটি ছোট অনলাইন দোকানের সাইট বানাচ্ছেন — রাজশাহীর নকশিকাঁথা বিক্রি হবে। এক সপ্তাহ পরে তাঁর প্রজেক্ট ফোল্ডারের চেহারা এমন:

nakshi-shop/
├── index.html
├── index-old.html
├── index-final.html
├── index-final-final.html
├── index_final_final2 (ক্লায়েন্টের পছন্দ).html
├── style.css
├── style-backup-jan.css
└── style NEW use this.css

কোনটা আসল? মেনুর বাগটা কোন দিন ঢুকেছিল? ক্লায়েন্ট বললেন, “গত মঙ্গলবারের ডিজাইনটাই ভালো ছিল” — কোন ফাইলটা মঙ্গলবারের? সমস্যাটা অলসতার নয় — ফাইলের নাম দিয়ে ইতিহাস রাখার পদ্ধতিটাই ভাঙা।

এর সমাধান version control — একটি টুল, যা আপনার প্রজেক্টের প্রতিটি সংরক্ষিত অবস্থার হিসাব রাখে: কে, কখন, কী বদলেছেন, আর কেন। ফাইল একটাই থাকে — index.html — আর তার পুরো ইতিহাস থাকে আলাদা একটি খাতায়। আজকের দুনিয়ায় সেই টুলের নাম প্রায় সব জায়গায় একটাই: Git.

বাড়ির জমির দলিলের কথা ভাবুন। জমি একটাই, কিন্তু ভূমি অফিসের খতিয়ানে লেখা থাকে কবে কার নামে গেল, কে সই করলেন, কোন দাগ নম্বর ভাগ হলো। পুরোনো মালিকানা জানতে জমি খুঁড়তে হয় না — খতিয়ান খুললেই হয়। Git আপনার প্রজেক্টের সেই খতিয়ান। আর প্রতিটি এন্ট্রি — একটি commit — হলো সেই মুহূর্তে পুরো প্রজেক্টের একটি হুবহু ছবি (snapshot), সাথে একটি ছোট বিবরণ।

Version control শুধু “ব্যাকআপ” নয়। এটি আপনাকে চারটি ক্ষমতা দেয়, যা ফাইল কপি করে কখনো পাওয়া যায় না:

ফিরে যাওয়া

যেকোনো commit-এ ফেরা যায় — পুরো প্রজেক্ট, বা শুধু একটি ফাইল।

“মঙ্গলবারের ডিজাইন দাও”

পার্থক্য দেখা

দুই সংস্করণের মধ্যে ঠিক কোন লাইন বদলেছে, লাইন ধরে দেখায়।

“বাগটা কোথায় ঢুকল?”

ঝুঁকিহীন পরীক্ষা

আলাদা শাখায় নতুন ডিজাইন চেষ্টা করুন; ভালো না লাগলে মূল কাজ অক্ষত।

dark mode চেষ্টা

দলে কাজ

কয়েকজন একই প্রজেক্টে কাজ করে পরিবর্তন মিলিয়ে নেন — ইমেইলে zip পাঠাতে হয় না।

ফ্রিল্যান্সিং, অফিস

Git-এর জন্ম ২০০৫ সালে। Linux kernel-এর হাজারো ডেভেলপার তখন BitKeeper নামের একটি বাণিজ্যিক টুল বিনামূল্যে ব্যবহার করতেন। সেই অনুমতি প্রত্যাহার হলে Linus Torvalds নিজেই কয়েক সপ্তাহের মধ্যে একটি নতুন টুল লিখে ফেলেন — Git. কয়েক মাস পরেই রক্ষণাবেক্ষণের দায়িত্ব নেন Junio Hamano, যিনি আজও এর প্রধান রক্ষণাবেক্ষণকারী। ২০০৮ সালে চালু হয় GitHub, যা Git-কে সাধারণ ডেভেলপারের হাতে পৌঁছে দেয়; ২০১৮ সালে Microsoft এটি কিনে নেয়।

এই পর্বের কমান্ডগুলো চালাতে হয় নিজের কম্পিউটারের terminal-এ। তাই কমান্ডের নিচে থাকবে “যা দেখার কথা” — আপনার স্ক্রিনে প্রায় এটাই আসবে (hash নম্বর আলাদা হবে)। Terminal-এর একেবারে প্রাথমিক ধারণা দরকার হলে কম্পিউটার ফান্ডামেন্টালস কোর্সের কমান্ড লাইন পর্বটি আগে দেখে নিতে পারেন।

২ · Git-এর ভিত্তি — ইনস্টল, init আর তিন জায়গার খেলা

ইনস্টল আর প্রথমবারের সেটিং

git-scm.com থেকে Git for Windows নামিয়ে ইনস্টল করুন। বেশিরভাগ প্রশ্নে ডিফল্ট উত্তরই ঠিক আছে। দুটি জিনিস খেয়াল রাখুন:

  • এর সাথে আসে Git Bash — একটি terminal, যেখানে অনলাইনের টিউটোরিয়ালের Linux-ধাঁচের কমান্ড (ls, touch, cat) চলে। চাইলে PowerShell বা VS Code-এর ভেতরের terminal-এও git চলবে।
  • সাথে আসে Git Credential Manager — প্রথমবার GitHub-এ push করার সময় এটিই ব্রাউজারে লগইন খুলে দেবে।

Terminal খুলে git --version লিখুন। Git না থাকলে macOS নিজেই Apple-এর Command Line Tools ইনস্টল করার প্রস্তাব দেবে — রাজি হলেই হবে। Homebrew ব্যবহার করলে brew install git.

Ubuntu বা Debian-এ একটি লাইনই যথেষ্ট:

sudo apt install git

ইনস্টলের পর একবার আপনার নাম আর ইমেইল জানিয়ে দিন — প্রতিটি commit-এ এগুলো লেখকের পরিচয় হিসেবে বসবে। আর নতুন repository-র মূল শাখার নাম main রাখার সেটিংটিও এখনই দিয়ে রাখুন (GitHub-ও এই নামই ব্যবহার করে):

git --version
git config --global user.name "Sabrina Akter"
git config --global user.email "sabrina@example.com"
git config --global init.defaultBranch main
# যা দেখার কথা (প্রথম লাইনের পর; নম্বর আলাদা হতে পারে)
git version 2.x.x
# config কমান্ডগুলো চুপচাপ কাজ সারে — কিছু না দেখানো মানেই সফল

প্রথম repository

এবার প্রজেক্ট ফোল্ডারে গিয়ে Git-কে বলুন, “এই ফোল্ডারের হিসাব রাখা শুরু করো।” এই একটি কমান্ডেই ফোল্ডারটি একটি repository হয়ে যায়:

cd nakshi-shop
git init
# যা দেখার কথা
Initialized empty Git repository in C:/Users/Sabrina/nakshi-shop/.git/

Git ফোল্ডারের ভেতরে একটি লুকানো .git ফোল্ডার বানিয়েছে — পুরো ইতিহাস থাকবে ওখানেই। এটি কখনো হাতে বদলাবেন না, আর মুছে ফেললে ইতিহাসও মুছে যাবে (ফাইলগুলো থেকে যাবে)। Git Bash-এ ls -a, PowerShell-এ ls -Force লিখলে লুকানো ফোল্ডারটি দেখা যায়।

ফোল্ডারে আমাদের প্রথম ফাইলটি এই — ছোট একটি দোকানের প্রথম পাতা। নিচের লেখা বদলে দেখুন; ঠিক এভাবে আপনি প্রতিদিন যা লেখেন, Git-এর ভাষায় সেটাই working directory-র পরিবর্তন:

<header>
  <h1>সাবরিনার নকশিকাঁথা</h1>
  <p>রাজশাহীর হাতে সেলাই করা কাঁথা — সারা দেশে ডেলিভারি</p>
</header>
<main>
  <h2>এই সপ্তাহের কাঁথা</h2>
  <ul>
    <li>লাল-সবুজ ফুলের নকশা — ২,৮০০ টাকা</li>
    <li>নীল পাখির নকশা — ৩,২০০ টাকা</li>
  </ul>
  <p><a href="contact.html">অর্ডার করতে যোগাযোগ করুন</a></p>
</main>

প্রিভিউতে একটি শিরোনাম, দুটি কাঁথার তালিকা আর একটি লিংক দেখবেন। লিংকে চাপলে প্রিভিউ শুধু জানাবে কোথায় যেত — contact.html এখনো বানানো হয়নি। চেষ্টা করুন: তৃতীয় একটি কাঁথা যোগ করুন, অথবা দাম বদলে দিন। নিজের কম্পিউটারে এমন বদল করে সেভ করলে git status লিখলেই Git বলবে modified: index.html — নিচের স্টেপারে ঠিক সেটাই দেখব।

তিন জায়গা — Git-এর সবচেয়ে গুরুত্বপূর্ণ ধারণা

নতুনরা সবচেয়ে বেশি গুলিয়ে ফেলেন এখানে: “সেভ তো করলাম, তবু commit হয়নি কেন?” কারণ Git-এর চোখে প্রতিটি পরিবর্তন তিনটি জায়গার কোনো একটিতে থাকে। পোস্ট অফিসের কথা ভাবুন — চিঠি লেখা (টেবিলে), খামে ভরে কাউন্টারে দেওয়া (ঠিক কোন চিঠিগুলো যাবে, বাছাই), আর সিল মেরে রেজিস্ট্রি খাতায় তোলা (চিরস্থায়ী রেকর্ড)। “পরে” চাপুন:

  1. Working directoryindex.htmlযেখানে লেখেন
  2. Staging areagit addপরের commit-এর বাছাই
  3. Repositorygit commitচিরস্থায়ী ইতিহাস
$ git statusনতুন ফাইল, Git এখনো হিসাব রাখছে না
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        index.html

nothing added to commit but untracked files present (use "git add" to track)
$ git add index.html → git statusখামে ভরা হলো
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   index.html
$ git commit -m "Add home page with product list"খাতায় উঠল
[main (root-commit) 3f2a1b7] Add home page with product list
 1 file changed, 12 insertions(+)
 create mode 100644 index.html
দাম বদলে সেভ → git statusবদল আছে, কিন্তু বাছাই হয়নি
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   index.html

no changes added to commit (use "git add" and/or "git commit -a")
$ git add index.html → git commit → git log --onelineদুটি মুহূর্ত, দুটি ছবি
9c41e0d (HEAD -> main) Update prices for winter collection
3f2a1b7 Add home page with product list
  1. ফাইল লিখলেন। index.html ফোল্ডারে আছে, কিন্তু Git একে “untracked” বলছে — অর্থাৎ চোখে দেখছে, হিসাব রাখছে না। Git কখনো নিজে থেকে কিছু সংরক্ষণ করে না; কোনটা রাখবেন, সিদ্ধান্ত আপনার। শেষ লাইনে Git নিজেই পরের কমান্ডের পরামর্শ দিচ্ছে — git status-এর লেখা মন দিয়ে পড়লে অর্ধেক প্রশ্নের উত্তর সেখানেই পাবেন।
  2. git add — খামে ভরা। ফাইলটি এখন staging area-য়: “পরের commit-এ এটি যাবে।” এই মাঝের ধাপ কেন? কারণ একদিনে আপনি হয়তো পাঁচটি ফাইল বদলেছেন — দুটি মেনুর বাগ ঠিক করতে, তিনটি নতুন পাতার জন্য। staging দিয়ে এদের আলাদা দুটি অর্থপূর্ণ commit বানানো যায়। সব একসাথে তুলতে git add . (ডট মানে “এই ফোল্ডারের সব”)।
  3. git commit — সিল মেরে খাতায়। staging-এ যা ছিল, তার একটি স্থায়ী ছবি তৈরি হলো। প্রতিটি commit পায় একটি অনন্য নম্বর — commit hash (এখানে 3f2a1b7, আপনার স্ক্রিনে অন্য হবে)। -m-এর পরের লেখাটি commit message. “root-commit” মানে এটি ইতিহাসের প্রথম commit.
  4. আবার বদলালেন। দাম বদলে সেভ করলেন। Git পার্থক্যটা ধরেছে — modified — কিন্তু লাল রঙে, “not staged”. সেভ করা আর commit করা আলাদা জিনিস: সেভ হলো টেবিলে চিঠি লেখা, commit হলো রেজিস্ট্রি খাতায় তোলা। ভুল বদল ফেলে দিয়ে শেষ commit-এর অবস্থায় ফিরতে চাইলে Git নিজেই বলছে: git restore index.html.
  5. দ্বিতীয় commit, আর ইতিহাস। আবার add আর commit করার পর git log --oneline দুটি মুহূর্ত দেখাচ্ছে — নতুনটি ওপরে। HEAD -> main মানে “আপনি এখন main শাখার এই commit-এ দাঁড়িয়ে।” এখন আর index-final-final.html লাগবে না — যেকোনো মুহূর্ত এই খাতাতেই আছে।
লিখুন → git add → git commit
টেবিল → কাউন্টার → রেজিস্ট্রি খাতা

Windows-এ দুটি সাধারণ ফাঁদ। (১) commit-এর সময় দেখতে পারেন warning: LF will be replaced by CRLF — এটি error নয়। Windows আর Linux লাইনের শেষ চিহ্ন (line ending) আলাদাভাবে লেখে, Git শুধু জানাচ্ছে সে মিলিয়ে নেবে। (২) Windows-এ ফাইলের নাম বড়-ছোট হাতের অক্ষরে আলাদা ধরা হয় না, কিন্তু প্রায় সব ওয়েব সার্ভার case-sensitive. Logo.PNG ফাইলকে HTML-এ logo.png লিখলে আপনার কম্পিউটারে ছবি দেখাবে, সার্ভারে ভাঙবে। নাম শুধু ছোট হাতের অক্ষর আর হাইফেনে রাখুন (পর্ব ০২-এর নিয়ম); নাম বদলাতে হলে git mv Logo.PNG logo.png ব্যবহার করুন, যাতে Git-ও বদলটা টের পায়।

৩ · ইতিহাস পড়া আর ভালো commit message

commit করার আসল লাভ পাওয়া যায় পরে — যখন ইতিহাস পড়তে হয়। দুটি কমান্ড সবচেয়ে বেশি কাজে লাগে: git log (কবে কী হলো) আর git diff (ঠিক কী বদলাল)।

git log --oneline        # প্রতিটি commit এক লাইনে
git diff                 # এখনো stage হয়নি এমন বদল
git diff --staged        # stage হয়েছে, commit হয়নি এমন বদল
git show 3f2a1b7         # একটি নির্দিষ্ট commit-এ কী বদলেছিল

দাম বদলের পর git diff চালালে এমন কিছু দেখবেন। - চিহ্নের লাইন মুছে গেছে, + চিহ্নের লাইন নতুন এসেছে — একে বলে diff:

# যা দেখার কথা (সংক্ষেপে)
diff --git a/index.html b/index.html
--- a/index.html
+++ b/index.html
@@ -7,3 +7,3 @@
   <ul>
-    <li>লাল-সবুজ ফুলের নকশা — ২,৮০০ টাকা</li>
+    <li>লাল-সবুজ ফুলের নকশা — ৩,০০০ টাকা</li>
     <li>নীল পাখির নকশা — ৩,২০০ টাকা</li>

ভালো commit message — ভবিষ্যতের আপনার জন্য চিঠি

ছয় মাস পরে আপনি বা আপনার সহকর্মী যখন git log পড়বেন, তখন কোড খুলে দেখার আগে শুধু message-গুলোই পড়বেন। “update”, “fix”, “changes” — এগুলো সেই সময় কিছুই বলে না। পেশাদার দলগুলো মোটামুটি এই নিয়মগুলো মানে:

  • প্রথম লাইন ছোট — মোটামুটি ৫০ অক্ষরের মধ্যে, শেষে দাঁড়ি বা ফুলস্টপ নয়। দরকার হলে একটি ফাঁকা লাইন দিয়ে নিচে বিস্তারিত (প্রতি লাইন ৭২ অক্ষরের মধ্যে) — একে প্রায়ই “৫০/৭২ নিয়ম” বলা হয়।
  • আদেশের ভঙ্গিতে, কী করে তা বলুন — “Add contact form”, “Fix broken logo path” — যেন বাক্যটি “এই commit প্রয়োগ করলে এটি…”-এর পরে বসে। Git নিজেও এভাবেই লেখে: Merge branch …, Revert ….
  • এক commit, এক উদ্দেশ্য — মেনুর বাগ আর নতুন পাতা আলাদা commit-এ। তাহলে একটিকে বাতিল করতে হলে অন্যটি অক্ষত থাকে।
  • “কেন”-টা লিখুন — কী বদলেছে diff-ই বলে দেয়; কেন বদলেছে, সেটা শুধু আপনিই জানেন।

বাংলায় message লেখা যায় (Git UTF-8 সামলায়), তবে দলে আর ওপেন-সোর্সে ইংরেজিই প্রচলিত। নিচের ছোট স্ক্রিপ্টটি একটি নকল git log --oneline ছাপে আর প্রতিটি message-কে ওপরের নিয়মে যাচাই করে:

// একটি নকল "git log --oneline" — আর প্রতিটি message-এর মান যাচাই
const commits = [
  { id: 'a1c9f02', msg: 'Add contact form with accessible labels' },
  { id: '7d3e4b1', msg: 'update' },
  { id: '5b2f8c9', msg: 'Fix broken logo path on about page' },
  { id: '3f2a1b7', msg: 'final changes done, fixed everything and also new css.' },
];

commits.forEach((c, i) => {
  const head = i === 0 ? ' (HEAD -> main)' : '';
  console.log(c.id + head + ' ' + c.msg);

  const problems = [];
  if (c.msg.length > 50) problems.push('too long (' + c.msg.length + ' chars)');
  if (c.msg.endsWith('.')) problems.push('ends with a full stop');
  if (c.msg.split(' ').length < 3) problems.push('too vague');
  if (!/^[A-Z]/.test(c.msg)) problems.push('start with a capital verb');
  console.log('    -> ' + (problems.length ? problems.join(', ') : 'OK'));
});

প্রথম আর তৃতীয় commit পাবে OK. update পাবে too vague, start with a capital verb — এক শব্দে কিছুই বোঝা যায় না। শেষটি পাবে too long (54 chars), ends with a full stop, start with a capital verb — আর আসল সমস্যা, এটি কয়েকটি আলাদা কাজ এক commit-এ গুঁজে দিয়েছে। চেষ্টা করুন: 'update'-কে 'Update winter prices for nakshi kantha' করে আবার চালান; তারপর নিজের একটি message লিখে দেখুন কোন নিয়মে আটকায়। (এটি শুধু অনুশীলন — আসল Git message-এর দৈর্ঘ্য নিয়ে কিছু বলে না।)

৪ · .gitignore আর গোপন তথ্য — যা কখনো commit হবে না

প্রতিটি প্রজেক্টে কিছু ফাইল থাকে যা ইতিহাসে রাখার মানে নেই, বা রাখা বিপজ্জনক: অপারেটিং সিস্টেমের আবর্জনা (Thumbs.db, .DS_Store), টুলের তৈরি বিশাল ফোল্ডার (node_modules/, যা পর্ব ৫০-এর Sass-PostCSS-এর মতো টুল ব্যবহারে আসে), লগ ফাইল — আর সবচেয়ে গুরুত্বপূর্ণ, গোপন চাবি। এদের তালিকা থাকে প্রজেক্টের মূল ফোল্ডারের .gitignore নামের একটি সাধারণ লেখার ফাইলে:

# অপারেটিং সিস্টেম আর এডিটরের ফাইল
.DS_Store
Thumbs.db
.vscode/

# টুলের তৈরি জিনিস — যেকোনো সময় আবার বানানো যায়
node_modules/
dist/
*.log

# গোপন তথ্য — কখনোই commit নয়
.env
.env.*
!.env.example

নিয়মগুলো সহজ: # দিয়ে মন্তব্য; * মানে “যেকোনো সংখ্যক অক্ষর” (তবে / নয়); শেষে / মানে শুধু ফোল্ডার; শুরুতে / মানে শুধু মূল ফোল্ডারে; আর ! দিয়ে আগের কোনো নিয়মের ব্যতিক্রম। একই ফাইলে একাধিক নিয়ম মিললে শেষের মিলটাই জেতে। নিচের সিমুলেটরটি এই মূল নিয়মগুলো দিয়ে কয়েকটি ফাইলের ভাগ্য ঠিক করে:

// ছোট একটি .gitignore সিমুলেটর (আসল Git আরও কিছু নিয়ম মানে)
const rules = ['*.log', 'node_modules/', '.env', '/drafts', '!important.log'];
const paths = ['index.html', 'error.log', 'important.log', 'node_modules/sass/index.js',
  '.env', 'css/.env', 'drafts/old.html', 'blog/drafts/post.html'];

function toRegex(p) {
  const dirOnly = p.endsWith('/'); if (dirOnly) p = p.slice(0, -1);
  const anchored = p.includes('/'); p = p.replace(/^\//, '');
  const body = p.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '[^/]*');
  return new RegExp((anchored ? '^' : '(^|/)') + body + (dirOnly ? '/' : '(/|$)'));
}

for (const f of paths) {
  let ignored = false, why = '(no rule)';
  for (const r of rules) {
    const neg = r.startsWith('!');
    if (toRegex(neg ? r.slice(1) : r).test(f)) { ignored = !neg; why = r; }
  }
  console.log((ignored ? 'IGNORED  ' : 'tracked  ') + f.padEnd(28) + '<- ' + why);
}

index.html কোনো নিয়মে পড়ে না — tracked. error.log আটকাল *.log-এ, কিন্তু important.log প্রথমে আটকে পরে !important.log-এ ছাড়া পেল — শেষের মিল জেতে। .env যেকোনো ফোল্ডারে আটকায় (css/.env-ও), কারণ নিয়মে / নেই। /drafts শুধু মূল ফোল্ডারের drafts ধরে, তাই blog/drafts/post.html tracked. চেষ্টা করুন: '/drafts'-কে 'drafts/' করে দেখুন — এবার দুটোই আটকাবে। আসল Git-এ আরেকটি নিয়ম আছে যা এখানে নেই: কোনো ফোল্ডার পুরোটা আটকালে তার ভেতরের ফাইল ! দিয়েও ফেরানো যায় না।

PowerShell-এর ফাঁদ: Windows PowerShell 5.1-এ echo ".env" > .gitignore লিখলে ফাইলটি UTF-16 এনকোডিংয়ে লেখা হয়, আর Git সেটি ঠিকমতো পড়তে পারে না — নিয়মগুলো চুপচাপ কাজ করে না। .gitignore সবসময় VS Code-এ বানান (নিচের স্ট্যাটাস বারে UTF-8 দেখাবে), অথবা Git Bash-এ echo ".env" >> .gitignore. আর .gitignore শুধু এখনো track না হওয়া ফাইল আটকায়; আগেই commit হয়ে থাকলে git rm --cached .env দিয়ে হিসাব থেকে সরাতে হয়।

গোপন তথ্য — একবার push মানে চিরকাল প্রকাশ্য

পেমেন্ট গেটওয়ের secret key, ইমেইল সেবার পাসওয়ার্ড, ডেটাবেসের পাসওয়ার্ড — এগুলো রাখা হয় .env ফাইলে, আর সেই ফাইল .gitignore-এ। কারণ Git-এর ইতিহাস মুছে ফেলা প্রায় অসম্ভব: পরের commit-এ চাবি মুছলেও আগের commit-এ সেটি থেকেই যায়, আর GitHub-এর public repository-তে স্বয়ংক্রিয় bot সারাক্ষণ এমন চাবি খোঁজে। GitHub-এর নিজের secret scanning কিছু পরিচিত ধরনের চাবি ধরতে পারে, কিন্তু তার ওপর ভরসা করে বসে থাকবেন না।

মূল নিয়ম

চাবি ভুল করে push হয়ে গেলে প্রথম কাজ ইতিহাস মোছা নয় — চাবিটি বাতিল করে নতুন চাবি নেওয়া (সেবার ড্যাশবোর্ড থেকে)। ধরে নিন সেটি ইতিমধ্যে কেউ দেখে ফেলেছে। আর একটি কথা static site-এর জন্য বিশেষভাবে সত্যি: HTML বা ব্রাউজারের JavaScript-এ যা লেখেন, তা প্রতিটি দর্শকের ব্রাউজারে যায় — View Source করলেই দেখা যায়। তাই গোপন চাবি কখনো front-end কোডে নয়; সেটা থাকে সার্ভারে।

৫ · Branch — মূল কাজ না ভেঙে নতুন কিছু চেষ্টা

সাইট চলছে, ক্রেতারা অর্ডার দিচ্ছেন। এখন সাবরিনা একটি dark mode (পর্ব ৩৬) যোগ করতে চান — কিন্তু অর্ধেক কাজ করা অবস্থায় মূল সাইট ভাঙতে চান না। সমাধান branch: ইতিহাসের একটি আলাদা ধারা, যেখানে যত খুশি পরীক্ষা চলবে, আর কাজ ভালো হলে মূল ধারায় মিলিয়ে নেওয়া (merge) হবে।

git branch                  # কোন কোন branch আছে, আপনি কোনটায় (* চিহ্ন)
git switch -c dark-mode     # নতুন branch বানিয়ে সেখানে যান
git switch main             # main-এ ফিরে যান
git merge dark-mode         # (main-এ দাঁড়িয়ে) dark-mode-এর কাজ মিলিয়ে নিন
git branch -d dark-mode     # মেলানো শেষ, নামটি মুছে দিন

পুরোনো টিউটোরিয়াল আর অনেক AI উত্তরে একই কাজ দেখবেন git checkout -b dark-mode দিয়ে — সেটিও চলে, কিন্তু checkout অনেক রকম কাজ করত বলে বিভ্রান্তিকর ছিল; তাই ২০১৯ সালে Git 2.23-এ আলাদা git switch আর git restore আসে। নিচে দেখুন ভেতরে কী ঘটে:

$ git log --oneline --graphশুরুর অবস্থা
* 9c41e0d (HEAD -> main) Update prices for winter collection
* 3f2a1b7 Add home page with product list
$ git switch -c dark-modeনতুন নাম, একই জায়গা
Switched to a new branch 'dark-mode'

* 9c41e0d (HEAD -> dark-mode, main) Update prices for winter collection
* 3f2a1b7 Add home page with product list
style.css বদলে → add → commit (দুবার)dark-mode এগোল, main থেমে আছে
* e7b2a90 (HEAD -> dark-mode) Respect prefers-color-scheme
* 4d8c3f1 Add dark colour tokens
* 9c41e0d (main) Update prices for winter collection
* 3f2a1b7 Add home page with product list
$ git switch mainফোল্ডারের ফাইল বদলে গেল!
Switched to branch 'main'

style.css খুলে দেখুন — dark mode-এর কোনো লাইন নেই।
ফাইল হারায়নি; Git ফোল্ডারটিকে main-এর ছবিতে ফিরিয়ে দিয়েছে।
$ git merge dark-modeFast-forward
Updating 9c41e0d..e7b2a90
Fast-forward
 style.css | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
দুই দিকে একই লাইন বদলালেmerge conflict
CONFLICT (content): Merge conflict in style.css
Automatic merge failed; fix conflicts and then commit the result.

<<<<<<< HEAD
  --accent: #c2410c;
=======
  --accent: #15803d;
>>>>>>> dark-mode
  1. শুরু। main শাখায় দুটি commit. --graph বাঁ পাশে * দিয়ে ইতিহাসের রেখা আঁকে। HEAD -> main — আপনি main-এ আছেন।
  2. নতুন শাখা। git switch -c dark-mode নতুন একটি নাম বানিয়ে আপনাকে সেখানে নিয়ে গেল। খেয়াল করুন, দুটি নামই একই commit 9c41e0d-এ — কোনো ফাইল কপি হয়নি। Branch বানানো তাই চোখের পলকের কাজ, প্রজেক্ট যত বড়ই হোক।
  3. শাখায় কাজ। dark mode-এর CSS লিখে দুটি commit করলেন। dark-mode নাম দুই ধাপ এগিয়েছে, কিন্তু main এখনো 9c41e0d-এ — লাইভ সাইটের কোড অক্ষত। এর মধ্যে মূল সাইটে জরুরি কোনো বাগ এলে main-এ ফিরে ঠিক করা যাবে।
  4. main-এ ফেরা। git switch main করার পর VS Code-এ style.css খুললে dark mode-এর লাইনগুলো নেই! ভয়ের কিছু নেই — Git আপনার working directory-কে main-এর শেষ ছবির মতো সাজিয়ে দিয়েছে; dark-mode-এর কাজ নিরাপদে তার নিজের commit-এ আছে। (commit না করা বদল থাকলে Git সেগুলো সাথে নিয়েই শাখা বদলায়; আর সেগুলো অন্য শাখার ফাইলের সাথে সংঘর্ষ করলে switch করতেই দেয় না — তাই শাখা বদলের আগে commit করে নেওয়াই নিরাপদ।)
  5. Merge. main-এ দাঁড়িয়ে git merge dark-mode. যেহেতু main এর মধ্যে আর এগোয়নি, Git শুধু main নামটিকে সামনে e7b2a90-এ সরিয়ে দিল — একে বলে fast-forward. দুই দিকেই নতুন commit থাকলে Git দুটো মিলিয়ে একটি নতুন “merge commit” বানাত।
  6. যখন মেলে না — conflict. ধরুন main-এ কেউ --accent রং কমলা করেছেন, আর dark-mode-এ আপনি সবুজ। Git জানে না কোনটা ঠিক, তাই ফাইলে দাগ দিয়ে দুটোই রাখে: <<<<<<< HEAD থেকে ======= পর্যন্ত আপনি এখন যে শাখায় দাঁড়িয়ে (এখানে main), তার রূপ; তার পর থেকে >>>>>>> পর্যন্ত অন্যটি। এই merge conflict সমাধান মানুষের কাজ: সঠিক লাইনটি রেখে দাগগুলো মুছুন, তারপর git add style.css আর git commit. VS Code এই অংশগুলো রঙিন করে “Accept Current / Incoming” বোতামও দেখায়।

আরও গভীরে: Git ভেতরে আসলে একটি ছোট “ঠিকানা দিয়ে খোঁজা” ডেটাবেস। প্রতিটি ফাইলের লেখা একটি blob, প্রতিটি ফোল্ডার একটি tree, আর প্রতিটি commit শুধু বলে “এই tree, এই parent commit, এই লেখক, এই message” — আর প্রত্যেকের নাম তার নিজের বিষয়বস্তুর hash (ঐতিহ্যগতভাবে SHA-1; নতুন Git SHA-256-এ repository বানাতেও পারে)। বিষয়বস্তুর একটি অক্ষর বদলালে hash বদলায়, তাই ইতিহাস চুপিচুপি বদলানো যায় না। আর একটি branch হলো .git/refs/heads/-এর ভেতরে একটি ছোট ফাইল, যার ভেতরে শুধু একটি commit hash লেখা — এজন্যই branch বানানো এত সস্তা, আর HEAD হলো সেই ফাইলের দিকে একটি নির্দেশ।

৬ · GitHub — অনলাইনের আলমারি আর push

এ পর্যন্ত সব ছিল আপনার কম্পিউটারে। ল্যাপটপ চুরি গেলে বা হার্ডডিস্ক নষ্ট হলে? সহকর্মী কীভাবে কাজ পাবেন? এখানে আসে remote — একই repository-র আরেকটি কপি, সাধারণত GitHub-এ। মনে রাখুন: Git একটি টুল, GitHub একটি সেবা। Git চলে আপনার কম্পিউটারে, GitHub সেই Git repository অনলাইনে রাখে আর তার চারপাশে issue, pull request, আর সাইট প্রকাশের মতো সুবিধা দেয়। একই কাজের অন্য সেবাও আছে — GitLab, Bitbucket, Codeberg.

repository বানিয়ে push করা

  1. github.com-এ অ্যাকাউন্ট খুলে ওপরের + → New repository. নাম দিন nakshi-shop, Public বা Private বেছে নিন। আপনার কম্পিউটারে আগেই repository থাকলে README বা .gitignore যোগের ঘরগুলো ফাঁকা রাখুন — নইলে প্রথম push-এ ইতিহাস না মেলার ঝামেলা হয়।
  2. GitHub পরের পাতায় নিজেই কমান্ডগুলো দেখাবে। সেগুলো এই:
git remote add origin https://github.com/sabrina-akter/nakshi-shop.git
git branch -M main
git push -u origin main
# যা দেখার কথা (সংখ্যাগুলো আলাদা হবে)
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Writing objects: 100% (9/9), 1.42 KiB | 1.42 MiB/s, done.
To https://github.com/sabrina-akter/nakshi-shop.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

git branch -M main শুধু নিশ্চিত করে যে আপনার শাখার নাম main — init.defaultBranch সেটিং না দিলে Git শাখার নাম master রাখতে পারে, তখন এটি নাম বদলে main করে দেয়; আগে সেটিংটি দিয়ে রাখলে এটি কিছুই বদলায় না, ক্ষতিও করে না। সবচেয়ে গুরুত্বপূর্ণ শেষ লাইনটি — একে ভেঙে দেখি:

git push -u origin main
  1. git — Git প্রোগ্রামকে ডাকা। এরপরের শব্দটিই বলবে কোন কাজ।
  2. push — “আমার কম্পিউটারের নতুন commit-গুলো remote-এ পাঠাও।” Push শুধু commit পাঠায় — সেভ করা কিন্তু commit না করা বদল যায় না। উল্টো দিকের কাজ pull: git pull GitHub-এর নতুন commit নামিয়ে মিলিয়ে নেয়।
  3. -u (পুরো নাম --set-upstream) — “এই শাখাটিকে ওই remote-এর শাখার সাথে জোড়া বেঁধে রাখো।” শুধু প্রথমবার লাগে। এরপর থেকে শুধু git push বা git pull লিখলেই Git জানে কোথায় যেতে হবে।
  4. origin — remote-এর ডাকনাম, যা git remote add origin … দিয়ে দিয়েছিলেন। “origin” কোনো বিশেষ শব্দ নয়, শুধু প্রচলিত নাম; git remote -v লিখলে ডাকনামের পেছনের আসল ঠিকানা দেখা যায়।
  5. main — কোন শাখা পাঠাবেন। dark-mode শাখা পাঠাতে চাইলে git push -u origin dark-mode. অন্য কম্পিউটারে পুরো প্রজেক্ট ইতিহাসসহ নামাতে: git clone https://github.com/sabrina-akter/nakshi-shop.git — একে বলে clone.

পরিচয় প্রমাণ — HTTPS না SSH?

GitHub-এ push করতে প্রমাণ দিতে হয় আপনি কে। ২০২১ সাল থেকে GitHub Git-এর কাজে সাধারণ অ্যাকাউন্ট-পাসওয়ার্ড নেয় না। দুটি পথ:

🔐 HTTPS (নতুনদের জন্য সহজ)

ঠিকানা https://github.com/…. Windows-এ Git Credential Manager প্রথম push-এ ব্রাউজারে লগইন খুলে দেয়, তারপর মনে রাখে। অন্য জায়গায় পাসওয়ার্ডের বদলে personal access token লাগে, অথবা GitHub CLI ইনস্টল করে gh auth login দিয়ে একবার লগইন করে নিতে পারেন।

শুরু করার জন্য এটাই

🗝️ SSH key

ঠিকানা git@github.com:…. একবার ssh-keygen -t ed25519 দিয়ে চাবিজোড়া বানিয়ে public অংশ (.pub ফাইল) GitHub-এর Settings → SSH keys-এ দিন। Private key কখনো কাউকে দেবেন না।

নিয়মিত ব্যবহারকারীদের প্রিয়

README.md — repository-র পরিচয়পত্র

GitHub repository-র প্রথম পাতায় README.md সাজিয়ে দেখায়। এটি লেখা হয় Markdown-এ — সহজ লেখার নিয়ম, যা GitHub নিজেই HTML-এ রূপ দেয়। নিয়োগকর্তা আগে README-ই পড়েন:

# সাবরিনার নকশিকাঁথা

রাজশাহীর হাতে সেলাই করা নকশিকাঁথার ছোট অনলাইন দোকান।
শুধু HTML আর CSS — কোনো framework নেই।

**লাইভ সাইট:** https://sabrina-akter.github.io/nakshi-shop/

## যা আছে
- রেসপন্সিভ লেআউট (CSS Grid)
- dark mode (`prefers-color-scheme`)
- অ্যাক্সেসিবল অর্ডার ফর্ম

৭ · সাইট প্রকাশ — তিনটি পথ

এবার আসল মুহূর্ত: আপনার ফোল্ডারের HTML-CSS ফাইল এমন একটি কম্পিউটারে তোলা, যা দিনরাত চালু থাকে আর পৃথিবীর যে কেউ ব্রাউজারে ঠিকানা লিখলে ফাইলগুলো পাঠায়। একে বলে deploy করা, আর সেই জায়গাকে web hosting. আমাদের সাইট static site — সার্ভারকে শুধু তৈরি ফাইল হুবহু পাঠাতে হবে, কিছু হিসাব করতে হবে না। এজন্য পথ অনেক, আর বেশিরভাগই বিনামূল্যে শুরু করা যায়।

পথ ১ — GitHub Pages: repository থেকে সরাসরি

কোড আগেই GitHub-এ থাকলে এর চেয়ে সহজ কিছু নেই। GitHub Pages একটি branch-এর ফাইলগুলোকেই ওয়েবসাইট বানিয়ে দেয়:

  1. repository-র Settings → Pages-এ যান।
  2. Build and deployment-এর Source-এ Deploy from a branch বেছে নিন। (অন্য বিকল্প GitHub Actions — build টুল ব্যবহার করলে কাজে লাগে; শুধু HTML-CSS-এ দরকার নেই।)
  3. Branch-এ main আর ফোল্ডার / (root) দিয়ে Save. (চাইলে শুধু /docs ফোল্ডারটিও প্রকাশ করা যায়।) বেছে নেওয়া ফোল্ডারে index.html থাকতে হবে — সেটিই সাইটের প্রথম পাতা।
  4. এক-দুই মিনিট পরে একই পাতায় লিংক আসবে: https://sabrina-akter.github.io/nakshi-shop/. এরপর প্রতিবার git push করলে সাইট নিজে থেকে হালনাগাদ হবে।

খেয়াল রাখুন: বিনামূল্যের GitHub অ্যাকাউন্টে Pages চলে শুধু public repository থেকে — private repository থেকে সাইট প্রকাশ করতে পেইড প্ল্যান লাগে। আর repository-র নাম যদি হুবহু <username>.github.io হয়, তাহলে সেটি আপনার “user site” — ঠিকানা হয় https://sabrina-akter.github.io/, শেষে কোনো ফোল্ডার ছাড়া। পোর্টফোলিওর জন্য এটিই আদর্শ (পর্ব ৫৪-এর ক্যাপস্টোনে কাজে লাগবে)।

ফোল্ডার-ঠিকানার ফাঁদ: project site থাকে /nakshi-shop/ ফোল্ডারের নিচে। তাই পাতায় href="/style.css" (root-relative, পর্ব ০৫) লিখলে ব্রাউজার খুঁজবে sabrina-akter.github.io/style.css-এ — যা নেই, ফলে CSS ছাড়া ন্যাড়া পাতা। href="style.css" বা href="css/style.css"-এর মতো relative path লিখুন; তাহলে সাইট যেকোনো ফোল্ডারে, যেকোনো হোস্টে চলবে।

পথ ২ — Netlify, Vercel, Cloudflare Pages

এই সেবাগুলো static site প্রকাশের জন্যই বানানো, আর সবারই বিনামূল্যের একটি স্তর আছে (সীমা আর শর্ত তাদের নিজের পাতায় দেখে নিন — এগুলো সময়ের সাথে বদলায়)। দুটি উপায়ে কাজ করে:

  • টেনে ছেড়ে দেওয়া (drag-and-drop): Netlify-তে লগইন করে প্রজেক্ট ফোল্ডারটি ব্রাউজারের নির্দিষ্ট জায়গায় টেনে ছেড়ে দিলেই কয়েক সেকেন্ডে একটি ঠিকানা (যেমন random-name.netlify.app) পাবেন। Git লাগে না, তবে প্রতিবার হাতে তুলতে হয়।
  • repository যুক্ত করা: GitHub অ্যাকাউন্ট যুক্ত করে repository বেছে নিন। এরপর প্রতিটি push-এ সেবাটি নিজে থেকে নতুন সংস্করণ প্রকাশ করে — একে বলে continuous deployment. আলাদা branch বা pull request-এর জন্য আলাদা পরীক্ষামূলক ঠিকানাও (deploy preview) দেয় — ক্লায়েন্টকে নতুন ডিজাইন দেখাতে চমৎকার।

শুধু HTML-CSS হলে “build command” ঘর ফাঁকা রাখুন আর “publish directory” দিন যে ফোল্ডারে index.html আছে। এই সেবাগুলো ফাইল ছড়িয়ে দেয় একটি CDN-এ — পৃথিবীর নানা শহরের সার্ভারে কপি থাকে, তাই ঢাকা বা টরন্টো, দুই জায়গা থেকেই সাইট দ্রুত খোলে।

পথ ৩ — শেয়ার্ড হোস্টিং, cPanel আর SFTP

বাংলাদেশের ব্যবসা আর ক্লায়েন্টের কাজে সবচেয়ে প্রচলিত পথ এখনো এটি: দেশি বা বিদেশি কোনো হোস্টিং কোম্পানি থেকে domain আর shared hosting প্যাকেজ কেনা, সাথে পাওয়া যায় cPanel. এর সুবিধা — একই জায়গায় info@yourshop.com.bd-এর মতো ইমেইল, PHP আর MySQL (পরে ডায়নামিক কিছু লাগলে), আর বাংলায় সাপোর্ট পাওয়ার সুযোগ। হোস্ট বাছাইয়ে দামের পাশাপাশি দেখুন বিনামূল্যে HTTPS, SFTP আর ব্যাকআপ আছে কি না।

  1. হোস্টের দেওয়া ঠিকানায় cPanel-এ লগইন করে File Manager খুলুন।
  2. public_html ফোল্ডারে ঢুকুন — এটি সাইটের document root; এর ভেতরের index.html-ই আপনার domain-এর প্রথম পাতা।
  3. নিজের কম্পিউটারে প্রজেক্টের ভেতরের ফাইলগুলো zip করুন (ফোল্ডারটি নয় — নইলে সাইট থাকবে yourshop.com.bd/nakshi-shop/-এ)। Upload দিয়ে zip তুলে, ডান-ক্লিক করে Extract.
  4. হোস্টের দেওয়া পুরোনো index.php বা “default” পাতা থাকলে সরিয়ে দিন, তারপর ব্রাউজারে domain খুলে দেখুন।

নিয়মিত হালনাগাদের জন্য ডেস্কটপ অ্যাপ সুবিধাজনক — বাঁ পাশে আপনার কম্পিউটার, ডান পাশে সার্ভার, টেনে ছেড়ে দিন। WinSCP শুধু Windows-এ, FileZilla সব OS-এ চলে।

  • Protocol: হোস্ট অনুমতি দিলে SFTP (সাধারণত port 22), নইলে “FTP with explicit TLS” (FTPS). সাধারণ FTP এড়িয়ে চলুন — পাসওয়ার্ড এনক্রিপশন ছাড়া যায়, পাবলিক Wi-Fi-তে বিপজ্জনক।
  • Host, username, password: হোস্টের স্বাগত-ইমেইল বা cPanel-এর “FTP Accounts” থেকে।
  • সংযোগের পর ডান পাশে public_html-এ গিয়ে ফাইল তুলুন। WinSCP-র “Synchronize” শুধু বদলানো ফাইলগুলো তোলে।

কোন পথ কখন

Choosing a way to publish

প্রয়োজনভালো পছন্দকেন
নিজের পোর্টফোলিও, শেখার প্রজেক্টGitHub Pagesকোড আর সাইট এক জায়গায়, push করলেই হালনাগাদ
ক্লায়েন্টের static সাইট, branch-এর প্রিভিউ দরকারNetlify / Vercel / Cloudflare Pagesঅটো-ডিপ্লয়, deploy preview, CDN
ব্যবসার সাইট, সাথে domain-ইমেইল আর পরে PHP ফর্মশেয়ার্ড হোস্টিং + cPanelসব এক প্যাকেজে, স্থানীয় সাপোর্ট
Git জানেন না, আজই একটা ডেমো দেখাতে হবেNetlify-তে drag-and-dropএক মিনিটে লিংক
ছবি ৫৩.১ — কোনো একটি পথ “সেরা” নয়; প্রয়োজন অনুযায়ী বাছুন। পরে পথ বদলানোও সহজ, কারণ ফাইলগুলো একই HTML-CSS.

কাস্টম 404 পাতা

কেউ ভুল ঠিকানা লিখলে বা পুরোনো লিংকে এলে সার্ভার পাঠায় 404 Not Found. হোস্টের সাদামাটা ইংরেজি পাতার বদলে নিজের একটি 404.html রাখুন, যা দর্শককে পথ দেখায়। GitHub Pages, Netlify আর Cloudflare Pages মূল ফোল্ডারের 404.html নিজে থেকেই ব্যবহার করে; cPanel-এ .htaccess ফাইলে একটি লাইন লাগে: ErrorDocument 404 /404.html.

<!doctype html>
<html lang="bn">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>পাতাটি পাওয়া যায়নি — সাবরিনার নকশিকাঁথা</title>
  <meta name="robots" content="noindex">
  <style>
    body { font-family: system-ui, sans-serif; max-width: 34rem; margin: 2rem auto;
           padding: 0 1rem; text-align: center; color: #1f2937; }
    .big { font-size: 4rem; font-weight: 800; color: #c2410c; margin: 0; }
    a { color: #1d4ed8; }
  </style>
</head>
<body>
  <main>
    <p class="big" aria-hidden="true">404</p>
    <h1>দুঃখিত, এই পাতাটি খুঁজে পাওয়া যায়নি</h1>
    <p>লিংকটি হয়তো পুরোনো, অথবা ঠিকানায় বানান ভুল আছে।</p>
    <p><a href="/">প্রথম পাতায় ফিরুন</a> · <a href="/products.html">সব কাঁথা দেখুন</a></p>
  </main>
</body>
</html>

মাঝখানে বড় কমলা “404”, নিচে একটি পরিষ্কার বাংলা শিরোনাম আর দুটি লিংক দেখবেন। তিনটি সূক্ষ্ম সিদ্ধান্ত খেয়াল করুন: (১) noindex — Google যেন এই পাতা সার্চে না দেখায়; (২) বড় “404”-এ aria-hidden, কারণ screen reader-এর জন্য শিরোনামটিই যথেষ্ট; (৩) লিংকগুলো / দিয়ে শুরু — 404 পাতা যেকোনো ঠিকানায় দেখা দিতে পারে (যেমন /blog/2024/old-post), সেখানে href="index.html" খুঁজত /blog/2024/index.html. ব্যতিক্রম GitHub project site — সেখানে লিখতে হবে /nakshi-shop/. চেষ্টা করুন: একটি সার্চ বা “জনপ্রিয় কাঁথা” তালিকা যোগ করুন, আর .big-এর রং বদলে দেখুন। লিংকে চাপলে প্রিভিউ শুধু ঠিকানাটি জানাবে।

৮ · নিজের domain, DNS আর HTTPS

sabrina-akter.github.io/nakshi-shop কাজ চলার মতো, কিন্তু দোকানের সাইনবোর্ডে লেখার মতো নয়। নিজের domain — ধরুন nakshibari.com.bd — কিনে সাইটের সাথে জুড়তে হলে domain আর DNS কীভাবে কাজ করে তা জানা দরকার। মূল ধারণাগুলো কম্পিউটার ফান্ডামেন্টালস কোর্সের Domain আর Hosting পর্বে বিস্তারিত আছে; এখানে শুধু প্রকাশের কাজে যা লাগে। (.bd domain দেশের নির্দিষ্ট নিবন্ধন ব্যবস্থার মাধ্যমে, সাধারণত কোনো রিসেলার হোস্টিং কোম্পানির হাত দিয়ে কেনা হয়; .com যেকোনো registrar থেকে।)

domain কেনার পর তার ঠিকানা-খাতায় — DNS-এ — কয়েকটি লাইন (DNS record) লিখতে হয়, যা বলে “এই নামের সাইট কোন সার্ভারে আছে।” দর্শক ঠিকানা লেখার পর কী কী ঘটে, ধাপে ধাপে দেখুন:

  1. দর্শকnakshibari.com.bdঠিকানা লিখলেন
  2. DNSA / CNAMEনাম → ঠিকানা
  3. TLScertificateপরিচয় যাচাই
  4. হোস্টindex.htmlফাইল পাঠায়
ব্রাউজারপ্রথম প্রশ্ন: এই নামের সার্ভার কোথায়?
https://nakshibari.com.bd/
ব্রাউজার শুধু নাম জানে। ইন্টারনেটে কম্পিউটার খোঁজা হয় IP ঠিকানা দিয়ে।
DNS record (GitHub Pages-এর উদাহরণ)domain প্যানেলে আপনি যা লেখেন
Type   Name   Value                       TTL
A      @      185.199.108.153             3600
A      @      185.199.109.153             3600
A      @      185.199.110.153             3600
A      @      185.199.111.153             3600
CNAME  www    sabrina-akter.github.io.    3600
TLS handshakeসার্ভার পরিচয়পত্র দেখায়
Certificate for: nakshibari.com.bd, www.nakshibari.com.bd
Issued by:       Let's Encrypt
Valid:           90 days (স্বয়ংক্রিয়ভাবে নবায়ন)
HTTP responseএবার আসল পাতা
HTTP/2 200
content-type: text/html; charset=utf-8
cache-control: max-age=600

<!DOCTYPE html><html lang="bn"> …
  1. ঠিকানা লেখা। দর্শক ব্রাউজারে domain লিখলেন। কিন্তু ইন্টারনেটে কম্পিউটার চেনা হয় সংখ্যার ঠিকানায় (IP), নামে নয় — তাই প্রথম কাজ নামটিকে ঠিকানায় বদলানো (পর্ব ০১-এর গল্প মনে করুন)।
  2. DNS-এর উত্তর। domain প্যানেলে আপনি যা লিখেছেন, সেটাই উত্তর। A record নামটিকে সরাসরি IP-তে পাঠায় (@ মানে খোদ domain); CNAME একটি নামকে আরেকটি নামের দিকে (www → sabrina-akter.github.io). উপরের চারটি IP GitHub Pages-এর ডকুমেন্টেশনে দেওয়া — তবে সবসময় সেবার নিজের পাতা থেকে মিলিয়ে নেবেন, AI বা পুরোনো ব্লগ থেকে নয়। Netlify বা cPanel হোস্ট তাদের নিজের মান দেয়। TTL বলে উত্তরটি কতক্ষণ cache-এ থাকবে — তাই DNS বদলের পর সবার কাছে পৌঁছাতে কয়েক মিনিট থেকে কয়েক ঘণ্টা (কখনো আরও বেশি) লাগতে পারে।
  3. পরিচয় যাচাই। https:// হলে সার্ভার একটি TLS certificate দেখায় — প্রমাণ যে সে সত্যিই এই domain-এর। এখানে দাতা Let's Encrypt, যা বিনামূল্যে স্বল্পমেয়াদি certificate দেয় (এখন সাধারণত ৯০ দিনের; মেয়াদ আরও কমানোর পরিকল্পনা ঘোষিত হয়েছে) আর হোস্ট মেয়াদ শেষের আগে নিজেই নবায়ন করে। GitHub Pages-এ Settings → Pages-এ custom domain লিখে “Enforce HTTPS” চালু করুন; Netlify-তে এটি নিজে থেকেই হয়; cPanel-এ সাধারণত “SSL/TLS Status” বা AutoSSL অংশে।
  4. পাতা এল। এনক্রিপ্ট করা সংযোগে সার্ভার পাঠাল status 200 আর আপনার index.html. ব্রাউজার এবার আগের পর্বগুলোর মতো HTML পড়ে, CSS এনে পাতা আঁকবে।

HTTPS চালুর পর দুটি কাজ বাকি থাকে। প্রথমত, http:// দিয়ে আসা দর্শককে https://-এ পাঠানো — GitHub Pages আর Netlify নিজেই করে; cPanel-এর Apache সার্ভারে .htaccess-এ:

# http → https, স্থায়ী redirect (301)
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# নিজের 404 পাতা
ErrorDocument 404 /404.html

দ্বিতীয়ত, পাতার ভেতরে কোথাও http:// দিয়ে ছবি বা স্ক্রিপ্ট আনা থাকলে তা বদলানো — নইলে ব্রাউজার সেগুলো mixed content বলে আটকে দেয়। DevTools-এর Console-এ এমন সতর্কবার্তা খুঁজুন (পর্ব ৪৭)।

৯ · প্রকাশের আগের চেকলিস্ট আর সাইট হালনাগাদ রাখা

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

কী যাচাইকীভাবেবিস্তারিত
HTML-এ error নেইvalidator.w3.org-এ প্রতিটি পাতাপর্ব ০৩
কোনো লিংক বা ছবি ভাঙা নয়প্রতিটি মেনু চেপে দেখা; DevTools-এর Network-এ লাল 404 খোঁজাপর্ব ০৫, ৪৭
কাস্টম 404 পাতা কাজ করেসাইটে একটি আজগুবি ঠিকানা খুলে দেখাঅংশ ৭
Favicon, title, meta descriptionট্যাবে আইকন আর শিরোনাম দেখা; প্রতিটি পাতার description আলাদাপর্ব ১৩
Open Graph প্রিভিউFacebook বা WhatsApp-এ লিংক পাঠিয়ে ছবি-শিরোনাম দেখাপর্ব ১৩
sitemap.xml আর robots.txtমূল ফোল্ডারে রাখা; Search Console-এ sitemap জমাপর্ব ১৩
মোবাইলে ঠিক দেখায়DevTools-এর device toolbar-এ ৩৬০ পিক্সেল; নিজের ফোনেওপর্ব ৩০
দ্রুত লোড হয়Lighthouse আর PageSpeed Insights; ছবির আকারপর্ব ৩২, ৪৯
সবার জন্য ব্যবহারযোগ্যশুধু Tab দিয়ে পুরো সাইট চালানো; Lighthouse Accessibility; contrastপর্ব ১২, ৪৫
অ্যানালিটিক্স (যদি দরকার)একটি পাতা খুলে রিয়েল-টাইম রিপোর্টে নিজেকে দেখানিচে

এর কিছু অংশ পাতা নিজেই নিজের ব্যাপারে বলতে পারে। নিচের পাতার শেষে একটি ছোট স্ক্রিপ্ট আছে, যা নিজের <head> আর ছবিগুলো পরীক্ষা করে ফল ছাপে:

<!doctype html>
<html lang="bn">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>সাবরিনার নকশিকাঁথা — রাজশাহীর হাতে সেলাই</title>
  <meta name="description" content="হাতে সেলাই করা নকশিকাঁথা, সারা দেশে ডেলিভারি।">
  <meta property="og:title" content="সাবরিনার নকশিকাঁথা">
</head>
<body>
  <h1>সাবরিনার নকশিকাঁথা</h1>
  <img src="../favicon.jpg" width="64" height="64">
  <p>নতুন কাঁথার ছবি শিগগির আসছে।</p>
  <script>
    const q = (s) => document.querySelector(s);
    const checks = [
      ['html lang', document.documentElement.lang],
      ['title (10+ chars)', document.title.length >= 10],
      ['meta description', q('meta[name="description"]')],
      ['viewport', q('meta[name="viewport"]')],
      ['og:image', q('meta[property="og:image"]')],
      ['favicon link', q('link[rel~="icon"]')],
      ['exactly one h1', document.querySelectorAll('h1').length === 1],
      ['every img has alt', [...document.images].every((i) => i.hasAttribute('alt'))],
    ];
    checks.forEach(([name, ok]) => console.log((ok ? 'PASS  ' : 'FAIL  ') + name));
  </script>
</body>
</html>

প্রিভিউতে শিরোনাম, একটি ছোট ছবি (এই সাইটেরই আইকন) আর একটি বাক্য; নিচে আটটি লাইন — পাঁচটি PASS, আর তিনটি FAIL: og:image, favicon link আর every img has alt. ঠিক করে দেখুন: <head>-এ <link rel="icon" href="favicon.png"> আর <meta property="og:image" content="https://nakshibari.com.bd/og.jpg"> যোগ করুন, ছবিতে alt="সাবরিনার নকশিকাঁথার লোগো" দিন — তিনটিই PASS হবে। মনে রাখুন, এ ধরনের পরীক্ষা শুধু “আছে কি না” দেখে; alt-এর লেখা অর্থবহ কি না, তা দেখতে হবে মানুষকেই।

sitemap আর robots.txt দুটোই সাধারণ লেখার ফাইল, সাইটের মূল ফোল্ডারে থাকে:

# robots.txt — সব সার্চ ইঞ্জিন সব পাতা দেখতে পারে
User-agent: *
Allow: /

Sitemap: https://nakshibari.com.bd/sitemap.xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url><loc>https://nakshibari.com.bd/</loc><lastmod>2026-10-20</lastmod></url>
  <url><loc>https://nakshibari.com.bd/products.html</loc></url>
  <url><loc>https://nakshibari.com.bd/contact.html</loc></url>
</urlset>

অ্যানালিটিক্স (web analytics): কতজন আসছেন, কোন পাতা জনপ্রিয় — জানতে Google Analytics বা গোপনীয়তা-বান্ধব কোনো বিকল্প যোগ করতে পারেন। তবে প্রতিটি বাড়তি স্ক্রিপ্ট পাতা ভারী করে, আর দর্শকের তথ্য সংগ্রহ করলে তা জানানো আপনার দায়িত্ব।

সাইট হালনাগাদ রাখা — প্রতিদিনের ছন্দ

প্রকাশের পর আসল কাজ শুরু: নতুন পণ্য, দাম বদল, ভুল ঠিক করা। Git থাকলে ছন্দটা সহজ:

git pull                          # অন্য কম্পিউটারে কাজ করে থাকলে আগে নতুনটা আনুন
# ... ফাইল বদলান, ব্রাউজারে দেখে নিন ...
git add .
git commit -m "Add three new winter kanthas"
git push                          # GitHub Pages / Netlify নিজে থেকে প্রকাশ করবে

cPanel-এ শুধু বদলানো ফাইলগুলো SFTP দিয়ে তুলুন — কিন্তু তার আগেও commit করুন, যাতে ইতিহাস থাকে। আরও কয়েকটি অভ্যাস: বড় পরিবর্তন আলাদা branch-এ করে deploy preview-তে দেখে তবে merge; CSS বদলালে style.css?v=2-এর মতো cache busting (পর্ব ১৬); আর domain-হোস্টিংয়ের নবায়নের তারিখ ক্যালেন্ডারে রাখা — মেয়াদ পেরোলে সাইট বন্ধ, domain হাতছাড়াও হতে পারে। সবচেয়ে বড় নিয়ম: সার্ভারে সরাসরি কিছু বদলাবেন না; সবকিছু Git-এর ভেতর দিয়ে।

১০ · AI-এর যুগে Git আর প্রকাশ

Git-এর কমান্ড আর হোস্টিংয়ের ধাপ AI খুব ভালো ব্যাখ্যা করতে পারে — আবার এখানেই এর ভুল সবচেয়ে ব্যয়বহুল হতে পারে। একটি ভুল HTML ট্যাগ পাতা একটু খারাপ দেখায়; একটি ভুল Git কমান্ড কয়েক দিনের কাজ মুছে দিতে পারে, আর একটি ভুল পরামর্শে পাসওয়ার্ড পৃথিবীর সামনে চলে যেতে পারে।

AI প্রায়ই যা বলেসমস্যাযা করবেন
git push --force দিয়ে “ঠিক করে নাও”remote-এর অন্যের commit মুছে যেতে পারেআগে git pull, কারণ বুঝুন; একান্ত দরকারে --force-with-lease
git reset --hardcommit না করা কাজ চিরতরে মুছে যায়আগে git status আর git stash; কমান্ডটি কী মোছে জিজ্ঞেস করুন
শুরুতেই git add ., কোনো .gitignore ছাড়া.env, node_modules repository-তে ঢোকেপ্রথম commit-এর আগে .gitignore; git status পড়ে তবে commit
API key সরাসরি JavaScript-এ বসানো কোডপ্রতিটি দর্শক চাবিটি দেখতে পানগোপন চাবি সার্ভারে; front-end-এ শুধু প্রকাশযোগ্য চাবি
পুরোনো DNS IP বা GitHub Pages-এর পুরোনো ধাপসাইট খোলে না বা HTTPS আসে নাসেবার অফিসিয়াল ডকুমেন্টেশন থেকে মিলিয়ে নিন
সাধারণ FTP-র নির্দেশনাপাসওয়ার্ড এনক্রিপশন ছাড়া যায়SFTP বা FTPS

Git-এ আটকে গেলে AI-কে অনুমান করতে দেবেন না — অবস্থা দেখিয়ে দিন। git status আর git log --oneline -5-এর আউটপুট পেস্ট করুন (কোনো পাসওয়ার্ড বা token থাকলে আগে মুছে নিন), আর কোনো কমান্ড চালানোর আগে সেটি কী মুছবে তা জিজ্ঞেস করুন:

আমি Windows 11-এ Git Bash ব্যবহার করি, একটি static HTML-CSS সাইট GitHub Pages-এ প্রকাশ করছি। git push করতে গিয়ে নিচের error এসেছে। আমার git status আর git log --oneline -5 এর আউটপুটও দিলাম: [এখানে error, git status আর git log আউটপুট পেস্ট করুন] ১. সহজ বাংলায় বলো আসলে কী ঘটেছে। ২. সবচেয়ে নিরাপদ সমাধান দাও — এমন কোনো কমান্ড দিও না যা commit বা remote-এর কাজ মুছে ফেলতে পারে। যদি কোনো ঝুঁকিপূর্ণ কমান্ড একান্তই লাগে, আগে স্পষ্ট করে বলো কী মুছবে আর কীভাবে আগে ব্যাকআপ নেব। ৩. প্রতিটি কমান্ডের পরে আমার স্ক্রিনে কী দেখার কথা, সেটাও লেখো।

AI-এর পরামর্শ মেনে প্রকাশের আগে — যাচাইয়ের চেকলিস্ট

পরীক্ষা ও ইন্টারভিউতে — বিশ্ববিদ্যালয়, চাকরি বা ফ্রন্ট-এন্ড ইন্টারভিউর পরীক্ষায় এ ধরনের প্রশ্ন প্রায়ই আসে:

  • Git আর GitHub-এর পার্থক্য? — Git নিজের কম্পিউটারে চলা version control টুল; GitHub Git repository অনলাইনে রাখার ও দলে কাজের সেবা।
  • working directory, staging area আর repository কী? — যেখানে লেখেন; git add দিয়ে পরের commit-এর বাছাই; git commit দিয়ে স্থায়ী ইতিহাস।
  • git pull আর git fetch-এর পার্থক্য? — fetch শুধু remote-এর নতুন commit নামায়; pull নামিয়ে বর্তমান branch-এ মিলিয়েও নেয় (fetch + merge).
  • merge conflict কখন হয়, কীভাবে মেটাবেন? — দুই branch একই জায়গা দুইভাবে বদলালে; দাগ দেওয়া অংশ হাতে ঠিক করে git add আর git commit.
  • static site কোথায় host করা যায়, HTTPS কেন? — GitHub Pages, Netlify, Vercel, Cloudflare Pages বা শেয়ার্ড হোস্টিং; HTTPS তথ্য এনক্রিপ্ট করে আর সার্ভারের পরিচয় যাচাই করে।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন। এগুলো আপনাকে কমান্ড-মুখস্থকারী থেকে কাজের ধারা বোঝা পেশাদার বানাবে।

প্র ০১Git-কে “distributed” বলা হয় কেন? আগের centralized টুলগুলোর চেয়ে এটা কেন জিতে গেল?

Git-এর আগে প্রচলিত ছিল centralized version control — ১৯৯০ সালের দিকের CVS, আর ২০০০ সালে শুরু হওয়া Subversion (SVN). সেখানে ইতিহাস থাকত একটিমাত্র কেন্দ্রীয় সার্ভারে। আপনার কম্পিউটারে থাকত শুধু ফাইলের সর্বশেষ কপি। commit করা, পুরোনো সংস্করণ দেখা, এমনকি log পড়া — সবকিছুর জন্য সার্ভারের সাথে সংযোগ লাগত। সার্ভার বন্ধ মানে দলের সবার কাজ বন্ধ; সার্ভারের ডিস্ক নষ্ট মানে ইতিহাস শেষ, যদি ব্যাকআপ না থাকে।

Distributed মডেলে প্রতিটি clone একটি পূর্ণ repository — পুরো ইতিহাসসহ। আপনি বিমানে বসে, বা লোডশেডিংয়ে ইন্টারনেট ছাড়া, commit করতে পারেন, branch বানাতে পারেন, পাঁচ বছর আগের সংস্করণ দেখতে পারেন। GitHub-এ যা থাকে তা “কেন্দ্র” শুধু প্রথা অনুযায়ী, প্রযুক্তিগতভাবে নয় — দলের যেকোনো সদস্যের কম্পিউটারে একই পূর্ণ ইতিহাস আছে।

Linux kernel-এর মতো প্রজেক্টে এটি অপরিহার্য ছিল: পৃথিবীজুড়ে হাজারো মানুষ, কারও কাছে সবার জন্য একটি কেন্দ্রীয় সার্ভারের অনুমতি থাকা বাস্তবসম্মত নয়। তাই ২০০৫ সালে BitKeeper-এর বিনামূল্যের অনুমতি প্রত্যাহারের পর Linus Torvalds এমন টুল চেয়েছিলেন যা দ্রুত, distributed, আর ইতিহাস চুপিচুপি বদলানো ঠেকায় (hash দিয়ে)। একই বছর Mercurial নামে আরেকটি distributed টুলও আসে; দীর্ঘদিন দুটি পাশাপাশি চলেছে।

Git জিতল গতি, সস্তা branch, Linux-এর মতো বিশাল প্রজেক্টে প্রমাণিত ব্যবহার — আর সম্ভবত সবচেয়ে বড় কারণ GitHub. দাম হিসেবে Git-এর কমান্ড নতুনদের কাছে বিভ্রান্তিকর বলে কুখ্যাত; এজন্যই পরে switch আর restore যোগ করতে হয়েছে।

মূল উপলব্ধি: কোনো একটি কেন্দ্রের ওপর নির্ভর না করা — এটা শুধু প্রযুক্তি নয়, নির্ভরযোগ্যতার নকশা। আপনার ল্যাপটপ, GitHub আর সহকর্মীর কম্পিউটার — যেকোনো একটি হারালেও পুরো ইতিহাস বাকি দুটিতে থেকে যায়।

প্র ০২GitHub তো একটি কোম্পানির সেবা — নিজের সব কাজ সেখানে রাখা কতটা নিরাপদ বা বুদ্ধিমানের?

প্রশ্নটা খুব বাস্তব। GitHub ২০০৮ সালে একটি ছোট স্টার্টআপ হিসেবে শুরু হয়, আর ২০১৮ সালে Microsoft কিনে নেয়। কেনার ঘোষণার পর কিছু ডেভেলপার প্রতিবাদে নিজেদের প্রজেক্ট GitLab-এ সরিয়ে নিয়েছিলেন — কারণ তখন Microsoft-এর ওপেন-সোর্সের সাথে সম্পর্ক নিয়ে অনেকের সন্দেহ ছিল। পরে বেশিরভাগই থেকে গেছেন, কিন্তু প্রশ্নটা থেকে গেছে: একটি কোম্পানির নীতি, দাম বা কোনো দেশের ওপর নিষেধাজ্ঞার নিয়ম বদলালে কী হবে?

এখানে Git-এর distributed স্বভাব আপনাকে বাঁচায়। আপনার কোড আর তার পুরো ইতিহাস আপনার প্রতিটি clone-এ আছে। GitHub কাল বন্ধ হয়ে গেলেও আপনি git remote set-url origin … দিয়ে নতুন ঠিকানা দিয়ে GitLab, Codeberg বা নিজের সার্ভারে push করে আগের মতো কাজ চালাতে পারবেন। কোড আটকে যাওয়ার ঝুঁকি তাই কম।

কিন্তু যা Git-এর অংশ নয়, তা আটকে যেতে পারে: issue, pull request-এর আলোচনা, wiki, GitHub Actions-এর স্বয়ংক্রিয় কাজ, GitHub Pages-এর সেটিং। এগুলো প্ল্যাটফর্মের নিজস্ব জিনিস — একে বলে vendor lock-in. Netlify বা Vercel-এর সাথেও একই কথা: আপনার HTML-CSS যেকোনো জায়গায় চলবে, কিন্তু তাদের বিশেষ redirect ফাইল, ফর্ম সেবা বা function ব্যবহার করলে সরে যাওয়া কঠিন হবে।

বুদ্ধিমানের কাজ তাই: (১) গুরুত্বপূর্ণ repository-র অন্তত একটি কপি আরেক জায়গায় — নিজের কম্পিউটার তো আছেই; (২) সাইটটি সাধারণ, মানসম্মত HTML-CSS-এ রাখা, যাতে যেকোনো হোস্টে তোলা যায়; (৩) নিজের domain ব্যবহার করা — তাহলে হোস্ট বদলালেও দর্শকের ঠিকানা একই থাকে, শুধু DNS বদলায়; (৪) অ্যাকাউন্টে two-factor authentication চালু রাখা।

মূল উপলব্ধি: সেবা ব্যবহার করুন, কিন্তু নির্ভরতা বুঝে। মানসম্মত ফাইল, নিজের domain আর Git-এর পূর্ণ কপি — এই তিনটি থাকলে কোনো প্ল্যাটফর্মই আপনাকে আটকে রাখতে পারবে না।

প্র ০৩Static site hosting এত সস্তা, এমনকি বিনামূল্যে কীভাবে হয়? আর কখন শেয়ার্ড হোস্টিং বা সার্ভার সত্যিই দরকার?

খরচের রহস্য লুকিয়ে আছে “সার্ভারকে কতটা কাজ করতে হয়” প্রশ্নে। একটি ডায়নামিক সাইটে (যেমন PHP আর MySQL দিয়ে চলা WordPress) প্রতিটি অনুরোধে সার্ভারকে কোড চালাতে হয়, ডেটাবেস থেকে তথ্য আনতে হয়, পাতা জোড়া লাগাতে হয়। প্রতিটি দর্শক মানে CPU আর মেমরির খরচ। আর সেই কোডে নিরাপত্তা-ত্রুটি থাকলে সার্ভার হ্যাক হওয়ার ঝুঁকি।

Static site-এ সার্ভার শুধু আগে থেকে তৈরি একটি ফাইল খুঁজে পাঠিয়ে দেয় — সবচেয়ে সস্তা কাজ। এমন ফাইল সহজেই CDN-এর শত শত সার্ভারে কপি করে রাখা যায়, যেখানে একই ফাইল লক্ষ দর্শককে বারবার পাঠানো হয়। হোস্টিং কোম্পানির জন্য একটি ছোট পোর্টফোলিও সাইটের খরচ এতই কম যে বিনামূল্যে দিলেও চলে — বিনিময়ে তারা ডেভেলপারদের নিজেদের প্ল্যাটফর্মে অভ্যস্ত করে, যাঁরা পরে বড় প্রজেক্টে টাকা দিয়ে বাড়তি সেবা নেন। নিরাপত্তাও ভালো: চালানোর মতো কোড নেই, তাই হ্যাক করার জায়গাও কম।

তবে static-এর সীমা আছে। ফর্মের তথ্য কোথায় যাবে? লগইন, কার্ট, পেমেন্ট, প্রতি দর্শকের আলাদা তথ্য? এগুলোর জন্য কোথাও না কোথাও সার্ভারের কোড লাগে। আধুনিক পথ হলো static পাতা রেখে নির্দিষ্ট কাজে বাইরের সেবা বা ছোট “serverless function” ব্যবহার করা। পুরোনো ও এখনো জনপ্রিয় পথ — শেয়ার্ড হোস্টিংয়ে PHP.

আরেকটি বিবেচনা নীতিমালা: বিনামূল্যের static সেবাগুলোর ব্যবহারের শর্ত আছে — যেমন GitHub Pages মূলত ব্যক্তিগত, প্রজেক্ট আর সংগঠনের পাতার জন্য, বড় বাণিজ্যিক দোকান চালানোর বিনামূল্যের হোস্টিং হিসেবে নয়। ক্লায়েন্টের ব্যবসার সাইট তোলার আগে শর্ত পড়ে নেওয়া পেশাদারিত্বের অংশ।

মূল উপলব্ধি: প্রথম প্রশ্ন “কোন হোস্ট সস্তা?” নয়, “সাইটটির কি প্রতিটি দর্শকের জন্য আলাদা কিছু হিসাব করতে হয়?” না হলে static — দ্রুত, সস্তা, নিরাপদ; হ্যাঁ হলে সার্ভারের কোড কোথায় চলবে, সেটা ভাবুন।

প্র ০৪একটা ছোট ব্যক্তিগত ব্লগে তো কোনো পাসওয়ার্ড বা পেমেন্ট নেই — তবু HTTPS কেন দরকার?

অনেক বছর ধরে এই যুক্তিটাই প্রচলিত ছিল: “HTTPS শুধু ব্যাংক আর অনলাইন কেনাকাটার জন্য।” সাধারণ সাইটে HTTPS ছিল ঝামেলার — certificate কিনতে টাকা লাগত, প্রতি বছর হাতে নবায়ন করতে হতো, সেটআপ ছিল জটিল। তাই ২০১০-এর দশকের শুরুতেও ওয়েবের বড় অংশ চলত সাধারণ HTTP-তে।

কিন্তু HTTP-তে আপনার পাতা যাওয়ার পথে যে কেউ — একই পাবলিক Wi-Fi-র কেউ, বা পথের কোনো নেটওয়ার্ক — পাতাটি পড়তে এবং বদলাতে পারে। বাস্তবে বিভিন্ন দেশে কিছু নেটওয়ার্ক অপারেটর HTTP পাতায় নিজেদের বিজ্ঞাপন বা স্ক্রিপ্ট ঢুকিয়ে দেওয়ার ঘটনা ঘটেছে। আপনার ব্লগে পাসওয়ার্ড নেই ঠিক, কিন্তু কেউ যদি পথে একটি ক্ষতিকর স্ক্রিপ্ট ঢুকিয়ে দেয়, দর্শকের চোখে দোষ আপনার সাইটের। আর কে কোন পাতা পড়ছেন — সেটাও ব্যক্তিগত তথ্য।

পরিবর্তন এল দুই দিক থেকে। ২০১৫-১৬ সালে চালু হয় Let's Encrypt — একটি অলাভজনক সংস্থা, যা বিনামূল্যে আর ACME নামের একটি protocol দিয়ে সম্পূর্ণ স্বয়ংক্রিয়ভাবে certificate দেয়। ছোট মেয়াদ (শুরু থেকে ৯০ দিন, সামনে আরও কমবে) ইচ্ছাকৃত: স্বয়ংক্রিয় নবায়নে বাধ্য করা, আর চাবি চুরি গেলে ক্ষতির সময় কমানো। অন্য দিকে ব্রাউজারগুলো ধীরে ধীরে HTTP পাতাকে ঠিকানার ঘরে “Not secure” দেখাতে শুরু করে; ২০১৮ সালে Chrome সব HTTP পাতার জন্যই এটা চালু করে।

এর সাথে প্রযুক্তিগত কারণও আছে: geolocation, ক্যামেরা, service worker-এর মতো অনেক আধুনিক ব্রাউজার-সুবিধা শুধু “secure context”-এ — মানে HTTPS-এ — চলে। দ্রুততর HTTP/2 আর HTTP/3-ও ব্রাউজারে কার্যত HTTPS-এর সাথেই আসে। আর সার্চ ইঞ্জিনগুলোও HTTPS-কে ইতিবাচকভাবে দেখে।

মূল উপলব্ধি: HTTPS এখন “বাড়তি নিরাপত্তা” নয়, ওয়েবের ন্যূনতম মান — আর GitHub Pages, Netlify বা বেশিরভাগ cPanel হোস্টে এটি এক ক্লিকে বা নিজে থেকেই বিনামূল্যে আসে। না চালানোর আর কোনো অজুহাত নেই।

প্র ০৫ভুল করে পাসওয়ার্ড বা API key commit করে push করে ফেলেছি — পরের commit-এ মুছে দিলেই কি সমস্যা শেষ?

না — আর কেন নয়, সেটা বুঝলে Git-এর মূল চরিত্রটাই বোঝা যায়। Git প্রতিটি commit-এ পুরো প্রজেক্টের একটি snapshot রাখে, আর প্রতিটি commit তার আগেরটির hash ধরে রাখে। আপনি নতুন commit-এ চাবিটি মুছলে শুধু নতুন snapshot-এ চাবি নেই; পুরোনো commit-এ সেটি অক্ষত আছে। যে কেউ git log -p বা GitHub-এর ইতিহাস পাতায় গিয়ে এক মিনিটে খুঁজে পাবেন।

ইতিহাস “নতুন করে লেখা” যায় — git filter-repo-এর মতো টুল দিয়ে সব commit থেকে ফাইলটি মুছে, তারপর force push. কিন্তু ততক্ষণে ক্ষতি হয়ে গেছে। public repository-র নতুন push প্রায় সাথে সাথেই স্বয়ংক্রিয় bot স্ক্যান করে — ক্লাউড সেবার চাবি পেলে কয়েক মিনিটের মধ্যে তা দিয়ে অন্যের খরচে কম্পিউটার চালানোর ঘটনা বহুবার ঘটেছে।

তাই সঠিক ক্রম: (১) চাবিটি এখনই বাতিল (revoke) করে নতুন চাবি নিন — এটাই একমাত্র নিশ্চিত সমাধান। (২) সেবার লগ দেখে নিন কেউ চাবিটি ব্যবহার করেছে কি না। (৩) তারপর ইচ্ছা হলে ইতিহাস পরিষ্কার করুন। (৪) ভবিষ্যতের জন্য .env আগে থেকেই .gitignore-এ, আর GitHub-এর secret scanning ও push protection-এর মতো সুবিধা চালু রাখুন — এগুলো কিছু পরিচিত চাবি push-এর মুহূর্তেই আটকাতে পারে।

Static site-এর জন্য একটি বাড়তি শিক্ষা আছে: ব্রাউজারে যাওয়া JavaScript-এ যে চাবি থাকে, তা কোনোভাবেই গোপন নয় — Git-এ না থাকলেও প্রতিটি দর্শক DevTools-এ দেখতে পান। কিছু সেবা এজন্যই “প্রকাশযোগ্য” চাবি দেয় (যেমন ম্যাপ বা ফায়ারবেসের ওয়েব কনফিগ), যার সুরক্ষা আসে domain-সীমা আর সার্ভারের নিয়ম থেকে, গোপনীয়তা থেকে নয়। কোন চাবি কোন ধরনের, সেবার ডকুমেন্টেশনে পড়ে নিন।

মূল উপলব্ধি: ইন্টারনেটে একবার প্রকাশিত জিনিস ফেরত আনা যায় না — তাই প্রতিকার নয়, প্রতিরোধ। আর প্রতিকার লাগলে আগে চাবি বদলান, পরে ইতিহাস।

অনুশীলন

নিজের কম্পিউটারে terminal খুলে করুন — প্রতিটি কমান্ডের পর git status পড়ার অভ্যাসটাই আসল শিক্ষা।

  1. তিন জায়গা হাতে-কলমে: একটি নতুন ফোল্ডারে git init করুন, index.html আর about.html বানান। শুধু index.html add করে git status দেখুন, commit করুন। তারপর দুটো ফাইলই বদলে আবার git status দেখুন। প্রতিবার কোন ফাইল কোন অংশে দেখাল?

    শুধু index.html add করার পর: Changes to be committed-এ new file: index.html, আর Untracked files-এ about.html. commit-এর পর about.html তখনো untracked. দুটো বদলানোর পর: index.html দেখাবে Changes not staged for commit … modified (Git এটা চেনে, আগে commit হয়েছে), আর about.html এখনো Untracked files-এ — কারণ Git কখনো একে track করেনি, তাই “modified” বলার মতো আগের অবস্থাও নেই। শিক্ষা: “modified” আর “untracked” আলাদা জিনিস, আর git add দুটোকেই staging-এ তোলে।

  2. .gitignore লিখুন: একটি প্রজেক্টে আছে index.html, css/style.css, images/, .env, node_modules/, debug.log, Windows-এর Thumbs.db আর notes/private-todo.txt (শুধু আপনার জন্য)। কোনগুলো commit হবে আর কোনগুলো নয় — একটি .gitignore লিখুন।

    commit হবে: index.html, css/, images/. বাকিগুলো আটকানোর একটি ভালো .gitignore:

    .env
    node_modules/
    *.log
    Thumbs.db
    /notes/

    /notes/-এর শুরুর / মানে শুধু মূল ফোল্ডারের notes; শেষের / মানে শুধু ফোল্ডার। কেউ যদি বলেন “images/-ও বাদ দিই, বড় ফাইল” — সেটা ভুল, সাইটের ছবি সাইটেরই অংশ; বরং ছবিগুলো আগে ছোট করুন (পর্ব ৩২)। ভালো অভ্যাস হিসেবে চাইলে একটি .env.example commit করতে পারেন, যেখানে শুধু নামগুলো থাকে, মান নয়।

  3. গোয়েন্দাগিরি: রাশেদ নিজের Windows ল্যাপটপে সাইট খুললে সব ঠিক। GitHub Pages-এ (rashed.github.io/tea-stall/) তুলে দেখলেন: CSS একদম নেই, আর লোগোর ছবি ভাঙা। HTML-এ আছে <link rel="stylesheet" href="/css/style.css"> আর <img src="images/logo.png" alt="টং দোকানের লোগো">; ফোল্ডারে ছবির নাম Logo.PNG. দুটি সমস্যা কী, কীভাবে ঠিক করবেন?

    CSS: /css/style.css root-relative, তাই ব্রাউজার খুঁজছে rashed.github.io/css/style.css — কিন্তু সাইট আছে /tea-stall/ ফোল্ডারে। সমাধান href="css/style.css" (relative). নিজের কম্পিউটারে Live Server প্রজেক্ট ফোল্ডারকেই মূল (/) ধরে চালায়, তাই সেখানে সমস্যাটা চোখে পড়েনি।

    ছবি: Windows বড়-ছোট হাতের অক্ষর আলাদা ধরে না, GitHub Pages-এর সার্ভার ধরে। logo.png আর Logo.PNG সেখানে দুটি ভিন্ন নাম। সমাধান: git mv Logo.PNG logo.png, তারপর commit আর push — শুধু Explorer-এ নাম বদলালে Windows-এর Git অনেক সময় বদলটা টের পায় না। দীর্ঘমেয়াদি নিয়ম: সব ফাইলের নাম ছোট হাতের অক্ষরে আর হাইফেনে। DevTools-এর Network প্যানেলে লাল 404 দেখলেই এ ধরনের সমস্যা দ্রুত ধরা যায়।

  4. পরামর্শক হিসেবে: তিনজন আপনার কাছে এসেছেন — (ক) কলেজের এক শিক্ষার্থী, যিনি চাকরির জন্য পোর্টফোলিও বানিয়েছেন; (খ) পুরান ঢাকার একটি মিষ্টির দোকান, যারা .com.bd domain, অফিসিয়াল ইমেইল আর পরে একটি অর্ডার ফর্ম চান; (গ) একটি এনজিও, যাদের তিনজন স্বেচ্ছাসেবক মাঝে মাঝে সাইটের খবর হালনাগাদ করবেন আর প্রতিটি বদল প্রকাশের আগে প্রধান সমন্বয়ক দেখে নিতে চান। কাকে কোন পথ দেবেন, কেন?

    (ক) GitHub Pages-এ username.github.io repository — কোড আর সাইট এক জায়গায়, আর নিয়োগকর্তা commit-এর ইতিহাস দেখে তাঁর কাজের ধারাও বুঝতে পারবেন। পরে চাইলে নিজের domain জুড়বেন।

    (খ) শেয়ার্ড হোস্টিং + cPanel — domain, info@… ইমেইল আর PHP ফর্ম এক প্যাকেজে; স্থানীয় সাপোর্ট। তবু কাজ Git-এ রাখুন আর SFTP দিয়ে তুলুন; HTTPS (AutoSSL/Let's Encrypt) চালু করতে ভুলবেন না।

    (গ) GitHub repository + Netlify/Vercel/Cloudflare Pages-এর মতো সেবা। প্রতিটি স্বেচ্ছাসেবক নিজের branch-এ কাজ করে pull request খুলবেন, সেবাটি একটি deploy preview বানাবে, সমন্বয়ক দেখে merge করলে তবেই মূল সাইট বদলাবে। এতে “অনুমোদন ছাড়া কিছু প্রকাশ নয়” নিয়মটি প্রযুক্তি দিয়েই নিশ্চিত হয়।

    খেয়াল করুন — তিনটিতেই HTML-CSS একই রকম; পার্থক্য শুধু মানুষ, প্রয়োজন আর কাজের ধারায়।

নিজেকে যাচাই করুন

ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।

ক্রমএকটি নতুন ফোল্ডার থেকে GitHub Pages-এ সাইট প্রকাশের ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. git init — ফোল্ডারটিকে repository বানানো
  2. git add . — ফাইলগুলো staging-এ তোলা
  3. git commit -m "…" — প্রথম snapshot
  4. git remote add origin … — GitHub-এর ঠিকানা যুক্ত করা
  5. git push -u origin main — commit পাঠানো
  6. Settings → Pages-এ branch বেছে প্রকাশ

একটি ফাইল বদলে সেভ করা হয়েছে, কিন্তু git add চালানো হয়নি। git commit চালালে কী হবে?

  • বদলটি স্বয়ংক্রিয়ভাবে commit হয়ে যাবে
  • বদলটি commit-এ যাবে না, কারণ সেটি staging-এ তোলা হয়নি
  • বদলটি মুছে যাবে
  • ফাইলটি repository থেকে সরিয়ে দেওয়া হবে

.gitignore ফাইলে .env লেখার মূল উদ্দেশ্য কী?

  • ফাইলটিকে এনক্রিপ্ট করা
  • ফাইলটি কম্পিউটার থেকে মুছে ফেলা
  • গোপন চাবি থাকা ফাইলটি যেন কখনো commit হয়ে repository-তে না যায়
  • সাইট দ্রুত লোড করা

একটি সাইট https://user.github.io/shop/ ঠিকানায় প্রকাশিত। পাতায় <link rel="stylesheet" href="/style.css"> লেখা থাকলে কী ঘটবে?

  • ব্রাউজার /shop/style.css লোড করবে
  • GitHub Pages নিজে থেকে ঠিক করে দেবে
  • HTTPS-এর কারণে ফাইলটি আটকে যাবে
  • ব্রাউজার user.github.io/style.css খুঁজবে, না পেয়ে CSS ছাড়াই পাতা দেখাবে

নিজের domain-এর www নামকে user.github.io-এর দিকে পাঠাতে সাধারণত কোন DNS record ব্যবহার হয়?

  • A record
  • CNAME record
  • MX record
  • TXT record

ভুল করে একটি পেমেন্ট সেবার secret key GitHub-এর public repository-তে push হয়ে গেছে। সবচেয়ে আগে কী করা উচিত?

  • পরের commit-এ চাবিটি মুছে দেওয়া
  • repository-টি private করে দেওয়া
  • সেবার ড্যাশবোর্ড থেকে চাবিটি বাতিল করে নতুন চাবি নেওয়া
  • .gitignore-এ ফাইলটির নাম যোগ করা

শেয়ার্ড হোস্টিংয়ে FileZilla দিয়ে ফাইল তোলার সময় কোন protocol সবচেয়ে কম নিরাপদ?

  • SFTP
  • FTP with explicit TLS (FTPS)
  • cPanel File Manager (HTTPS-এ)
  • সাধারণ FTP

শব্দকোষ

লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:

মনে রাখুন

  1. Git প্রতিটি commit-এ পুরো প্রজেক্টের snapshot রাখে; ফাইলের নামে ইতিহাস রাখার দিন শেষ।
  2. তিন জায়গা: working directory → git add → staging → git commit → repository; সন্দেহ হলে git status.
  3. প্রথম commit-এর আগে .gitignore; গোপন চাবি কখনো Git-এ বা front-end কোডে নয় — ফাঁস হলে আগে চাবি বদলান।
  4. git switch -c দিয়ে branch-এ পরীক্ষা, git merge দিয়ে মেলানো; git push -u origin main দিয়ে GitHub-এ।
  5. প্রকাশ: GitHub Pages, Netlify/Vercel/Cloudflare Pages বা cPanel + SFTP; relative path, নিজের domain, HTTPS আর চেকলিস্ট মিলিয়ে তবেই লিংক শেয়ার।

পরের পর্বে: এতদিন যা শিখেছেন — semantic HTML, রেসপন্সিভ লেআউট, আধুনিক CSS, অ্যাক্সেসিবিলিটি আর আজকের Git ও প্রকাশ — সব এক জায়গায়। ক্যাপস্টোনে নিজের একটি পূর্ণ পোর্টফোলিও সাইট বানিয়ে ইন্টারনেটে প্রকাশ করবেন।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

এই পর্বটি শেয়ার করুন:
এই পর্বে ভুল পেয়েছেন? জানান