VPS-এ সেরা self-hosted web analytics টুল নির্বাচন
আপনার VPS-এর জন্য Plausible, Umami, Matomo বা GoAccess বেছে নেওয়ার সঠিক উপায় জানুন। RAM-এর প্রয়োজনীয়তা, ডাটাবেস কনফিগারেশন এবং অ্যাড ব্লকার এড়িয়ে ডেটা সংগ্রহের খুঁটিনাটি এখানে দেখুন।
কোন self-hosted web analytics টুলটি আপনার VPS-এ চালানো উচিত?
Self-hosted web analytics মূলত দুটি ক্যাটাগরিতে বিভক্ত, এবং ভুল ক্যাটাগরি নির্বাচন করা ভুল প্রোডাক্ট নির্বাচনের চেয়েও বেশি ব্যয়বহুল হতে পারে। প্রথম ক্যাটাগরির টুলগুলো ভিজিটরের ব্রাউজারে একটি ছোট স্ক্রিপ্ট চালায় এবং সেই স্ক্রিপ্ট যা রিপোর্ট করে তা সংরক্ষণ করে। দ্বিতীয় ক্যাটাগরির টুলগুলো আপনার ওয়েব সার্ভারের তৈরি করা access log ফাইলটি পড়ে। এরপরের সবকিছু, যার মধ্যে ডাটাবেস এবং প্রয়োজনীয় মেমোরি অন্তর্ভুক্ত, তা এই প্রাথমিক সিদ্ধান্তের ওপর নির্ভর করে।
ছোট সার্ভারের জন্য সংক্ষিপ্ত উত্তর হলো: GoatCounter এবং Medama 1 GB RAM-এ চালানো সম্ভব, কারণ প্রতিটি টুল একটি ফাইলের ওপর ভিত্তি করে একটি মাত্র প্রসেস হিসেবে চলে। Umami একটি Postgres কন্টেইনার যোগ করে এবং এমন একটি ড্যাশবোর্ড প্রদান করে যা একজন নন-টেকনিক্যাল ব্যক্তিও সহজে বুঝতে পারেন। Plausible Community Edition এবং Rybbit উভয়ই ClickHouse ব্যবহার করে, তাই অন্তত 2 GB বা তার বেশি RAM-এর পরিকল্পনা রাখুন। Matomo একটি পূর্ণাঙ্গ প্রোডাক্ট এবং এটি আপনার ট্রাফিকের ওপর ভিত্তি করে সার্ভারের সাইজ নির্ধারণ করতে বলে। GoAccess ওয়েব পেজে কোনো বাড়তি লোড যোগ করে না, কারণ এটি বিদ্যমান লগ ফাইল থেকে তথ্য সংগ্রহ করে।
Script tag বা server log: কোনটি কী দেখতে পায়
একটি script tag ব্রাউজার পরিমাপ করে। পেজ লোড হওয়ার পর script রান করে এবং আপনার collector-এর কাছে একটি request পাঠায়। এই চেইনটি ভেঙে গেলে তা আপনার কাছে অদৃশ্য থেকে যায়: JavaScript বন্ধ থাকা, request ব্লক করে এমন কোনো filter list, collector-এর কাছে request ব্যর্থ হওয়া, অথবা এমন কোনো crawler যা script রান করে না।
একটি log parser request পরিমাপ করে। আপনি কিছু ইনস্টল করুন বা না করুন, আপনার web server প্রতিটি request-এর জন্য একটি লাইন লেখে, তাই ডেটা ইতিমধ্যেই ডিস্কে থাকে। এটি প্রতিটি crawler এবং এমন ফাইলের প্রতিটি hit দেখতে পায় যেখানে কোনো script tag নেই। এটি ব্রাউজারের ভেতরে কী ঘটেছে তা দেখতে পায় না, এবং এটি ব্রাউজার cache বা আপনার সার্ভারের সামনে থাকা কোনো CDN (content delivery network) থেকে পরিবেশিত পেজ দেখতে পায় না, কারণ সেই request আপনার সার্ভারে পৌঁছায়নি।
এই দুটি সংখ্যা মিলবে না, এবং এর কোনোটিই ভুল নয়। Matomo উভয় পদ্ধতিই ব্যবহার করতে পারে, এবং এটি তার JavaScript tracker-এর তুলনায় log import-এর সীমাবদ্ধতাগুলো নথিভুক্ত করে: screen resolution এবং page titles, events, content tracking, heatmaps, session recordings এবং form analytics। ব্রাউজারের পরিবর্তে request গণনা করার মূল্য হলো এই তালিকাটি।
Bot traffic হলো এই পার্থক্যের অন্য অর্ধেক। Log-ভিত্তিক গণনায় crawler অন্তর্ভুক্ত থাকে যদি না আপনি সেগুলোকে filter করেন, এবং সাধারণ সাইটে crawler-এর সংখ্যা এত বেশি হয় যে তা আপনার সিদ্ধান্তে প্রভাব ফেলতে পারে। GoAccess এবং Matomo-এর log import উভয়ই পরিচিত bot-গুলোকে filter করে। কোনোটিই এমন crawler-কে filter করতে পারে না যা তার user agent সম্পর্কে মিথ্যা তথ্য দেয়, আর এটিই log-ভিত্তিক গণনার সাথে server-এ AI crawler ব্লক করা যুক্ত করার এবং ব্লক করার আগে নয় বরং পরে log পড়ার একটি ভালো কারণ।
GoAccess: আপনার কাছে থাকা লগ থেকে অ্যানালিটিক্স
প্রকল্পটির নিজস্ব Debian এবং Ubuntu রিপোজিটরি থেকে এটি ইনস্টল করুন, কারণ ডিস্ট্রিবিউশনের প্যাকেজগুলো মূল রিলিজের তুলনায় পিছিয়ে থাকে।
wget -O - https://deb.goaccess.io/gnugpg.key | gpg --dearmor | sudo tee /usr/share/keyrings/goaccess.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/goaccess.gpg arch=$(dpkg --print-architecture)] https://deb.goaccess.io/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/goaccess.list
sudo apt-get update
sudo apt-get install goaccessএরপর এটিকে লগের দিকে নির্দেশ করুন এবং একটি স্ট্যাটিক রিপোর্ট তৈরি করুন।
goaccess /var/log/nginx/access.log -o ~/report.html --log-format=COMBINEDসাধারণ ব্যবহারকারীর ক্ষেত্রে এই কমান্ডটি Permission denied ত্রুটির কারণে ব্যর্থ হয়, কারণ Ubuntu-তে Nginx লগের মালিকানা root-এর এবং এর গ্রুপ হলো adm। sudo usermod -aG adm $USER ব্যবহার করে নিজেকে সেই গ্রুপে যুক্ত করুন, তারপর লগ আউট করে পুনরায় লগ ইন করুন, কারণ গ্রুপ মেম্বারশিপ লগ ইন করার সময় পড়া হয়। id চালান এবং পুনরায় চেষ্টা করার আগে নিশ্চিত করুন যে তালিকায় adm দেখা যাচ্ছে।
লাইভ লগের রিপোর্ট শুধুমাত্র সেই অংশটুকু কভার করে যা logrotate এখনো সরিয়ে নেয়নি। গতকালের অনুরোধগুলো access.log.1-এ থাকে এবং পুরোনো ফাইলগুলো কম্প্রেস করা থাকে, তাই সাপ্তাহিক ভিউ পাওয়ার জন্য রোটেট করা ফাইলগুলোও পড়তে হয়।
zcat /var/log/nginx/access.log.*.gz | goaccess - --log-format=COMBINED -o ~/last-week.htmlএখানে একটি লাইভ মোডও আছে, --real-time-html, যা WebSocket-এর মাধ্যমে পেজ আপডেট করে। এর জন্য একটি দ্বিতীয় পোর্ট এবং নিজস্ব প্রক্সি রুল প্রয়োজন। বেশিরভাগ সাইটের জন্য cron দ্বারা প্রতি ঘণ্টায় তৈরি করা রিপোর্টই যথেষ্ট এবং এতে নিরাপত্তার ঝুঁকিও কম থাকে।
GoatCounter: একটি Go binary এবং একটি SQLite ফাইল
GoatCounter একটি statically compiled binary হিসেবে রিলিজ হয়, তাই আলাদা কোনো runtime ইনস্টল করার প্রয়োজন নেই। রিলিজ পেজ থেকে একটি build ডাউনলোড করে সরাসরি চালান অথবা ইমেজ ব্যবহার করুন।
docker run -p 8080:8080 -v goatcounter-data:/home/goatcounter/goatcounter-data arp242/goatcounterbinary হিসেবে চালানোর সময়, goatcounter serve পোর্ট 8080-এ listen করে এবং ./goatcounter-data/db.sqlite3-এ SQLite ফাইল তৈরি করে। যখন instance-টি কোনো proxy-র পেছনে থাকে, তখন web wizard-এর পরিবর্তে command line থেকে প্রথম সাইটটি তৈরি করুন।
goatcounter db create site -vhost=stats.example.com -user.email=me@example.comএটি goatcounter serve -listen=:443 -tls=tls,rdr,acme ব্যবহার করে ACME (automatic certificate management environment)-এর মাধ্যমে নিজস্ব certificate পরিচালনা করতে পারে, যা এমন সার্ভারের জন্য উপযোগী যেখানে অন্য কোনো সার্ভিস চলে না। যেখানে Nginx বা Caddy ইতিমধ্যে পোর্ট 443 ব্যবহার করছে, সেখানে GoatCounter-কে 8080 পোর্টে রেখে তার দিকে proxy কনফিগার করুন। প্রজেক্টের তথ্য অনুযায়ী tracking script-টির আকার প্রায় 3.5K এবং JavaScript সমর্থন করে না এমন পেজের জন্য একটি tracking pixel রয়েছে। যদি ব্যস্ত সাইটের ক্ষেত্রে SQLite সীমাবদ্ধতা হয়ে দাঁড়ায়, তবে একই binary goatcounter serve -db 'postgresql+dbname=goatcounter' ব্যবহার করে Postgres-এর সাথে কাজ করতে পারে। ব্যাকআপ নেওয়ার জন্য কেবল ফাইলটি কপি করলেই হয়, যা এই ধরনের টুলের ক্ষেত্রে সবচেয়ে বড় সুবিধা।
Medama: একটি সিঙ্গেল কন্টেইনার যা 256 এমবি মেমোরি দাবি করে
Medama হলো এই তালিকার নতুনতম সিঙ্গেল বাইনারি অপশন। এটি ডিজাইন অনুযায়ী কুকি-মুক্ত এবং প্রজেক্টটির দাবি অনুযায়ী এর ট্র্যাকার 1 কেবি-র কম। এছাড়া 256 এমবি মেমোরিযুক্ত ভার্চুয়াল মেশিনে ছোট সাইটগুলো চালানো সম্ভব। এগুলো প্রজেক্টটির প্রকাশিত দাবি, এই গাইডের জন্য পরিমাপ করা সংখ্যা নয়।
docker volume create medama-data
docker run -d -p 127.0.0.1:8080:8080 -v medama-data:/app/data ghcr.io/medama-io/medama:latestঅফিসিয়াল কমান্ডটি পোর্টটিকে 8080:8080 হিসেবে পাবলিশ করে। উপরের লুপব্যাক প্রিফিক্সটি ইচ্ছাকৃতভাবে দেওয়া হয়েছে এবং রিভার্স প্রক্সি সেকশনে এর কারণ ব্যাখ্যা করা হয়েছে। প্রথম লগইন হলো CHANGE_ME_ON_FIRST_LOGIN পাসওয়ার্ড দিয়ে admin, এবং সেই পাসওয়ার্ডের নামটিই হলো নির্দেশনা।
নথিবদ্ধ একটি ব্যর্থতার কারণ আপনাকে সমস্যায় ফেলতে পারে। লগইন শুধুমাত্র HTTPS অথবা localhost-এ কাজ করে, তাই আপনি যদি সার্টিফিকেটের আগেই প্রক্সি সেটআপ করেন, তবে ফর্মটি সঠিক পাসওয়ার্ডকেও প্রত্যাখ্যান করবে এবং এর কারণ প্রদর্শন করবে না। প্রথমে TLS (ট্রান্সপোর্ট লেয়ার সিকিউরিটি) সেটআপ সম্পন্ন করুন, তারপর লগইন করুন।
Umami: Postgres এবং পরিচিত ড্যাশবোর্ড
git clone https://github.com/umami-software/umami.git
cd umami
docker compose up -dএটি 3000 পোর্টে অ্যাপ্লিকেশনটি চালু করে এবং এর পাশাপাশি একটি PostgreSQL কন্টেইনার সচল করে। ডকুমেন্টেশন অনুযায়ী ন্যূনতম PostgreSQL v12.14 এবং সোর্স থেকে বিল্ড করলে Node.js 18.18 বা তার পরবর্তী ভার্সন প্রয়োজন। একটি প্রি-বিল্ট ইমেজ রয়েছে, docker.umami.is/umami-software/umami:postgresql-latest, যার জন্য DATABASE_URL ব্যবহার করে আপনার চলমান ডাটাবেসের সাথে সংযোগ স্থাপন করতে হয়।
প্রথমবার লগইন করার জন্য ইউজারনেম admin এবং পাসওয়ার্ড umami ব্যবহার করুন। DNS কনফিগার করার আগেই এটি পরিবর্তন করে নিন, কারণ রেকর্ডটি রিজলভ হওয়ার সাথে সাথে এবং প্রক্সি সাড়া দেওয়া শুরু করলেই ইনস্ট্যান্সটি ইন্টারনেট থেকে অ্যাক্সেসযোগ্য হয়ে যায়। Compose-এর বিস্তারিত তথ্য, এনভায়রনমেন্ট ফাইল এবং রিস্টার্ট পলিসির জন্য একটি VPS-এ Docker Compose স্ট্যাক দেখুন; না পড়ে কোনো স্ট্যাক কপি করবেন না।
এর রিসোর্স ব্যবহারের পরিমাণ হলো একটি Node প্রসেস এবং Postgres। এটি একটি সিঙ্গেল বাইনারি ফাইলের চেয়ে ভারী হলেও ClickHouse ব্যবহারকারী যেকোনো কিছুর চেয়ে অনেক হালকা।
Plausible Community Edition: ClickHouse-এর জন্য RAM-এর নূন্যতম সীমা নির্ধারণ
git clone -b v3.2.1 --single-branch https://github.com/plausible/community-edition plausible-ce
cd plausible-ce
touch .env
echo "BASE_URL=https://stats.example.com" >> .env
echo "SECRET_KEY_BASE=$(openssl rand -base64 48)" >> .env
docker compose up -dআগস্ট 2026 অনুযায়ী v3.2.1 সংস্করণটি বর্তমান, এবং clone কমান্ডটি উদ্দেশ্যমূলকভাবে এই সংস্করণটিকেই নির্দিষ্ট করে। এই স্ট্যাকটি তিনটি অংশে বিভক্ত: অ্যাপ্লিকেশন, অ্যাকাউন্ট ও সেটিংসের জন্য Postgres, এবং ইভেন্ট ডেটার জন্য ClickHouse। SECRET_KEY_BASE অবশ্যই অন্তত 64 বাইটের একটি স্ট্রিং হতে হবে, যা openssl কলটির মাধ্যমে তৈরি করা হয়।
Plausible-এর নিজস্ব প্রয়োজনীয়তা অনুযায়ী অন্তত 2 GB RAM থাকা আবশ্যক, যাতে ClickHouse এবং অ্যাপ্লিকেশনটি out of memory killer-এর কবলে না পড়ে। এছাড়া এমন একটি CPU প্রয়োজন যা SSE 4.2 অথবা NEON সমর্থন করে, যা ClickHouse-এর জন্য জরুরি। সার্ভার কেনার আগে এই দ্বিতীয় শর্তটি যাচাই করা গুরুত্বপূর্ণ, এবং এটি ARM এবং x86 VPS-এর মধ্যে নির্বাচনের ক্ষেত্রে অন্যতম ব্যবহারিক পার্থক্য। ClickHouse তার উপলব্ধ মেমরির পুরোটা ব্যবহার করার চেষ্টা করে, তাই শেয়ার্ড সার্ভারে Compose-এ কন্টেইনারের মেমরি সীমাবদ্ধ করার নিয়ম অনুযায়ী একটি সর্বোচ্চ সীমা নির্ধারণ করে দিন।
BASE_URL অবশ্যই পাবলিক URL-এর সাথে হুবহু মিলতে হবে। যদি তা না মেলে, তবে আপনি লগইন করার পর অ্যাপ্লিকেশনটি ভুল হোস্টের দিকে রিডাইরেক্ট করবে এবং সেশন কুকি এমন একটি ডোমেইনে লেখা হবে যেখানে আপনার ব্রাউজার নেই। ফলে কোনো ত্রুটির বার্তা ছাড়াই আপনি পুনরায় লগইন ফর্মে ফিরে আসবেন।
প্রদত্ত compose ফাইলে কোনো পোর্ট পাবলিশ করা থাকে না, কারণ এর সামনে একটি প্রক্সি থাকার প্রত্যাশা করা হয়। একটি override যোগ করুন যা শুধুমাত্র loopback ইন্টারফেসে ডিফল্ট অ্যাপ্লিকেশন পোর্টটি পাবলিশ করবে।
cat > compose.override.yml << EOF
services:
plausible:
ports:
- 127.0.0.1:8000:8000
EOFMatomo: সম্পূর্ণ প্রোডাক্ট এবং এর জন্য প্রয়োজনীয় সার্ভার
Matomo PHP এবং MySQL বা MariaDB-তে চলে, যার মানে এটি কন্টেইনার স্ট্যাকের পরিবর্তে ক্লাসিক ওয়েব স্ট্যাকের সাথে সামঞ্জস্যপূর্ণ। এটি এই তালিকার একমাত্র টুল যা ট্রাফিক ভলিউম অনুযায়ী হার্ডওয়্যার নির্দেশিকা প্রকাশ করে।
The data behind this chart
[
{
"label": "100K/month",
"cpu_cores": 2,
"ram_gb": 2,
"disk_gb": 50
},
{
"label": "1M/month",
"cpu_cores": 4,
"ram_gb": 8,
"disk_gb": 250
},
{
"label": "10M/month",
"cpu_cores": 8,
"ram_gb": 16,
"disk_gb": 400
}
]এগুলো 2026 সালের আগস্ট মাস পর্যন্ত Matomo-এর প্রকাশিত ন্যূনতম প্রয়োজনীয়তা, এই গাইডের জন্য পরিমাপ করা কোনো তথ্য নয়। মাসে 1,00,000 পেজভিউ পর্যন্ত এটি 2 CPU কোর, 2 GB RAM এবং 50 GB SSD দাবি করে এবং একটি সার্ভারেই অ্যাপ্লিকেশন ও ডেটাবেস উভয়ই থাকে। 1M/month-এ এটি 8 GB RAM এবং 250 GB ডিস্কে পরিণত হয়। 10M/month-এ Matomo দুটি সার্ভারের পরামর্শ দেয় এবং শেষ সারিতে ডেটাবেস সার্ভারের তথ্য দেওয়া হয়েছে: 16 GB RAM এবং 400 GB ডিস্ক। এই ডিস্কের পরিসংখ্যানগুলো সিঙ্গেল বাইনারি অপশনগুলোর পাশে দেখুন, যেখানে পুরো ডেটাসেটটি একটি মাত্র SQLite ফাইল হিসেবে থাকে।
আর্কাইভিং বিষয়টি মানুষকে অবাক করে। ডিফল্টভাবে Matomo যখন কেউ ড্যাশবোর্ড খোলে তখন রিপোর্ট তৈরি করে, তাই ডেটা বাড়ার সাথে সাথে ড্যাশবোর্ড ধীর হয়ে যায় এবং একসময় টাইম-আউট হয়। এর নথিভুক্ত সমাধান হলো জেনারেল সেটিংসে ব্রাউজার ট্রিগারড আর্কাইভিং বন্ধ করা এবং এর পরিবর্তে cron থেকে আর্কাইভার চালানো। এটি Matomo ডিরেক্টরি থেকে, Matomo ফাইলের মালিকানাধীন ব্যবহারকারীর মাধ্যমে করতে হবে।
php console core:archive --url=https://analytics.example.comMatomo তার প্রসেস করা রিপোর্ট টেবিলের পাশাপাশি র-লগ টেবিলও রাখে এবং এটি সময়সূচী অনুযায়ী পুরনো র-ডেটা ও পুরনো রিপোর্ট মুছে ফেলতে পারে। ডিস্ক পূর্ণ হওয়ার আগেই ইনস্টলেশনের সময় এই ফিচারটি চালু করুন। Matomo সার্ভার অ্যাক্সেস লগও ইম্পোর্ট করতে পারে, যা এটিকে এই তালিকার একমাত্র প্রোডাক্ট করে তোলে যা একই সাথে উভয় ধরনের ডেটা হ্যান্ডেল করতে সক্ষম।
Rybbit এবং নতুন স্ট্যাকসমূহ
git clone https://github.com/rybbit-io/rybbit.git
cd rybbit
chmod +x *.sh
./setup.sh your.domain.nameRybbit একটি নতুন প্রজেক্ট যার একটি আধুনিক ড্যাশবোর্ড রয়েছে। এর সেটআপ স্ক্রিপ্টটি environment file তৈরি করে এবং Docker Compose ব্যবহার করে স্ট্যাকটি চালু করে। এটি ClickHouse চালায় এবং নিজস্ব ওয়েব সার্ভার হিসেবে Caddy ব্যবহার করে, যা 443 পোর্ট দখল করে এবং আপনার দেওয়া ডোমেইনের জন্য সার্টিফিকেট সংগ্রহ করে। যদি সার্ভারে ইতিমধ্যে Nginx 443 পোর্ট ব্যবহার করে থাকে, তবে স্ক্রিপ্টটি পোর্ট বাইন্ড করতে পারবে না। সেক্ষেত্রে প্রজেক্টের ম্যানুয়াল Compose পদ্ধতি ব্যবহার করুন এবং এটিকে আপনার বিদ্যমান প্রক্সির পেছনে রাখুন। ডকুমেন্টেশন অনুযায়ী এর জন্য কমপক্ষে 2 GB RAM প্রয়োজন, এটি Ubuntu 24 LTS-এ পরীক্ষিত এবং ClickHouse-এর কারণে ARM-এর ক্ষেত্রে ARMv8.2-A বা তার পরবর্তী ভার্সন প্রয়োজন।
যেকোনো নতুন প্রজেক্টের ক্ষেত্রে একটি সতর্কমূলক বিষয় হলো: এতে দ্রুত নতুন ফিচার যোগ হয় এবং সেই সাথে ব্রেকিং চেঞ্জও আসে। তাই নির্দিষ্ট ভার্সন ট্যাগ ব্যবহার করুন, নতুন ভার্সন পুল করার আগে release notes পড়ুন এবং সবার আগে ডাটাবেজের ব্যাকআপ নিন।
Retention এবং ডিস্কের আকার বৃদ্ধি: আপনার সার্ভারে এটি পরিমাপ করুন
ডিস্কের আকার বৃদ্ধি নির্ভর করে প্রতিটি ইভেন্টের জন্য টুলটি কী পরিমাণ ডেটা সংরক্ষণ করছে তার ওপর। GoatCounter হিটগুলোকে কাউন্টারে একত্রিত করে, তাই এর ফাইলের আকার raw ভলিউমের চেয়ে স্বতন্ত্র পেজ এবং দিনের সংখ্যার ওপর বেশি নির্ভর করে। Umami এবং Matomo প্রতিটি ইভেন্টের জন্য আলাদা সারি সংরক্ষণ করে, আর Matomo raw ডেটার পাশাপাশি প্রসেস করা রিপোর্টের টেবিলও জমা রাখে। ClickHouse ইভেন্টগুলোকে কলাম আকারে সংরক্ষণ করে এবং সেগুলোকে ব্যাপকভাবে কম্প্রেস করে, যার ফলে Plausible এমন ট্রাফিক ভলিউম সামলাতে পারে যা সাধারণ row store-এর জন্য কঠিন হতো।
এই নির্দেশিকায় প্রতি মিলিয়ন পেজভিউয়ের জন্য কত মেগাবাইট জায়গা প্রয়োজন তার কোনো নির্দিষ্ট সংখ্যা দেওয়া হয়নি, কারণ আপনার ট্রাফিকের ওপর ভিত্তি করে এটি পরিমাপ করা হয়নি। আপনি নিজেই এই পরিমাপটি করুন। আপনার Compose ফাইলে থাকা service এবং user-এর নাম অনুযায়ী নিচের কমান্ডটি সমন্বয় করে নিন।
du -h goatcounter-data/db.sqlite3
docker compose exec db psql -U umami -d umami -c "SELECT pg_size_pretty(pg_database_size('umami'));"
docker compose exec plausible_events_db clickhouse-client -q "SELECT formatReadableSize(sum(bytes_on_disk)) FROM system.parts WHERE active"সংখ্যাটি রেকর্ড করুন, এক সপ্তাহ অপেক্ষা করুন, পুনরায় রেকর্ড করুন এবং প্রাপ্ত পার্থক্যকে সেই সপ্তাহের ড্যাশবোর্ডে দেখানো পেজভিউয়ের সংখ্যা দিয়ে ভাগ করুন। এই সংখ্যাটি আপনার সাইট এবং বট ফিল্টারিংয়ের ওপর ভিত্তি করে তৈরি, তাই যেকোনো প্রকাশিত গড়ের চেয়ে এটি আপনার জন্য বেশি কার্যকর। সংখ্যাটি ছোট থাকতেই একটি retention limit সেট করুন। ডিস্ক পূর্ণ হয়ে গেলে শুধু অ্যানালিটিক্স নয়, VPS-এর প্রতিটি সার্ভিস বন্ধ হয়ে যাবে। এটিই সবচেয়ে বড় কারণ কেন ডেটাবেস ভলিউম এমন জায়গায় রাখা উচিত যেখানে df -h আপনাকে সতর্ক করতে পারবে। যদি আপনার সার্ভারে আগে থেকেই বড় কোনো ফাইল থাকে, তবে এই ঝুঁকিটি আরও গুরুত্বের সাথে দেখা উচিত, কারণ একটি self-hosted ফটো সার্ভার অ্যানালিটিক্স ডেটাবেসের অনেক আগেই ডিস্কের জায়গা শেষ করে ফেলবে।
রিভার্স প্রক্সির পেছনে এটি যেভাবে কাজ করে
কালেক্টরটিকে আপনার সাইটের একটি সাবডোমেইনে রাখুন, যেমন stats.example.com। এটি কালেক্টরের অনুরোধকে ফার্স্ট-পার্টিতে পরিণত করে, ফলে ব্রাউজারের থার্ড-পার্টি রিকোয়েস্ট ব্লকিং রুলগুলো একে বাধা দিতে পারে না।
কন্টেইনার পোর্ট পাবলিশ করার সময় অ্যাপ্লিকেশনটিকে লুপব্যাক (loopback) ইন্টারফেসে বাইন্ড করুন। Docker তার নিজস্ব ফায়ারওয়াল রুলগুলো ufw-এর আগেই লিখে ফেলে, তাই -p 3000:3000 হিসেবে পাবলিশ করা কন্টেইনার ইন্টারনেট থেকে অ্যাক্সেসযোগ্য থাকে, এমনকি যখন ufw status বলে যে পোর্টটি ডিনাই করা আছে। অন্য একটি মেশিন থেকে curl http://SERVER_IP:3000 দিয়ে পরীক্ষা করুন, আপনি ড্যাশবোর্ডটি দেখতে পাবেন। -p 127.0.0.1:3000:3000 হিসেবে পাবলিশ করলে একই পরীক্ষায় Connection refused দেখাবে এবং শুধুমাত্র প্রক্সিই এটি অ্যাক্সেস করতে পারবে।
server {
listen 443 ssl;
server_name stats.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}এখানে ফরওয়ার্ডিং হেডারগুলো ঐচ্ছিক নয়। X-Forwarded-For ছাড়া প্রতিটি ভিজিট 127.0.0.1 থেকে আসে বলে গণ্য হয়, ফলে কান্ট্রি রিপোর্ট খালি থাকে এবং ইউনিক ভিজিটর সংখ্যা কমে এক হয়ে যায়। প্রতিটি প্রজেক্ট নির্ধারণ করে তারা কোন হেডারকে বিশ্বাস করবে এবং কোন সেটিংসে কাজ করবে, তাই অনুমান না করে একবার প্রক্সির ডকুমেন্টেশন দেখে নিন। Caddy নিজে থেকেই এই হেডারগুলো সেট করে, এবং একই কাজের জন্য একটি Caddyfile মাত্র দুই লাইনের হয়।
stats.example.com {
reverse_proxy 127.0.0.1:3000
}আপনি যদি এখনো কোনো প্রক্সি নির্বাচন না করে থাকেন, তবে nginx, Caddy এবং Traefik-এর তুলনা নিবন্ধটি পড়ুন; সেখানে কয়েকটি সাবডোমেইনসহ একটি সিঙ্গেল সার্ভারের জন্য কোনটি উপযুক্ত তা আলোচনা করা হয়েছে।
আপনি যদি নিজে হোস্টিং (self-host) করেন, তবে কি কুকি ব্যানার প্রয়োজন?
নিজে হোস্টিং করলে ডেটা কার কাছে থাকছে তা পরিবর্তিত হয়, কিন্তু ডেটা সংক্রান্ত আইন পরিবর্তিত হয় না। দুটি নিয়ম আলাদাভাবে বিবেচনা করুন। ePrivacy-এর সম্মতির নিয়মটি ভিজিটরের ডিভাইসে কোনো কিছু সংরক্ষণ বা পড়ার সাথে সম্পর্কিত। তাই যে টুল কোনো কুকি সেট করে না এবং লোকাল স্টোরেজে কিছু লেখে না, তা এই নির্দিষ্ট প্রয়োজনীয়তার আওতার বাইরে থাকে। GDPR ব্যক্তিগত ডেটা প্রসেস করার সাথে সম্পর্কিত এবং IP address-কে ব্যক্তিগত ডেটা হিসেবে গণ্য করা হয়। তাই আপনার কাছে অবশ্যই একটি বৈধ ভিত্তি, ডেটা সংরক্ষণের সময়সীমা এবং কেউ আপনার কাছে থাকা তার তথ্য সম্পর্কে জানতে চাইলে উত্তর দেওয়ার ব্যবস্থা থাকতে হবে।
Plausible, Umami, GoatCounter এবং Medama ডিফল্টভাবে কোনো কুকি সেট করে না। প্রতিটি টুল কী ধরনের তথ্য সংগ্রহ করে তা প্রজেক্ট ভেদে ভিন্ন এবং ভার্সন পরিবর্তনের সাথে সাথে পরিবর্তিত হতে পারে। তাই কোনো সারসংক্ষেপের ওপর নির্ভর না করে প্রজেক্টের নিজস্ব প্রাইভেসি ডকুমেন্টেশন পড়ুন। Matomo-তে IP anonymisation এবং একটি opt out endpoint রয়েছে, যা আপনি অ্যাডমিন ইন্টারফেস থেকে সক্রিয় করতে পারেন।
বিভিন্ন দেশের নিয়ন্ত্রক সংস্থা ভিন্ন ভিন্ন সিদ্ধান্তে পৌঁছায়। উদাহরণস্বরূপ, ফ্রান্সের CNIL এমন কিছু শর্ত প্রকাশ করেছে যার অধীনে অডিয়েন্স পরিমাপের টুলগুলোকে সম্মতির প্রয়োজনীয়তা থেকে অব্যাহতি দেওয়া যেতে পারে। এই অংশটি তথ্যের একটি সারসংক্ষেপ মাত্র, কোনো আইনি পরামর্শ নয়। প্রকৃত ব্যবহারকারীসহ কোনো ওয়েবসাইটের ক্ষেত্রে আপনার এখতিয়ারভুক্ত এলাকার একজন আইনজীবীর পরামর্শ নিন।
একটি বিষয় যা অনেকেই এড়িয়ে যান: access log-ও ব্যক্তিগত ডেটা। GoAccess পেজে কোনো স্ক্রিপ্ট যোগ করে না, কিন্তু এটিও IP address প্রসেস করে। তাই লগ-ভিত্তিক অ্যানালিটিক্স স্বয়ংক্রিয়ভাবে নিয়মের আওতার বাইরে নয়।
Ad blockers এবং কেন আপনার পরিসংখ্যান কমে যাবে
Filter list-গুলো hostname এবং URL pattern-এর ওপর ভিত্তি করে কাজ করে। একটি hosted analytics product-কে শনাক্ত করা সহজ, কারণ সবাই একই সুপরিচিত hostname থেকে এটি লোড করে। collector-কে নিজের subdomain-এ সরিয়ে নিলে অনুরোধ থেকে সেই hostname-টি সরে যায় এবং আপনার বেছে নেওয়া path থেকে script পরিবেশন করলে সুপরিচিত filename-টিও আর থাকে না। এই দুটি পদক্ষেপই filter list-এর ম্যাচ করার প্রক্রিয়াকে বদলে দেয়।
এই পোস্টে কোনো নির্দিষ্ট hit rate-এর দাবি করা হয়নি, কারণ এটি পরিমাপ করা হয়নি। কতজন ভিজিটর আপনার সেটআপ ব্লক করবে তা আপনার অডিয়েন্সের ওপর নির্ভর করে; সাধারণ অডিয়েন্সের তুলনায় ডেভেলপার অডিয়েন্স অনেক বেশি ব্লক করে থাকে। এর পরিবর্তে আপনার নিজের ব্যবধান পরিমাপ করুন। একই সপ্তাহে GoAccess ব্যবহার করে access log-এ HTML পেজের অনুরোধ গণনা করুন এবং আপনার script-ভিত্তিক টুল যে pageview রিপোর্ট করছে তার সাথে তুলনা করুন। এই পার্থক্যের কারণ হলো ব্লক হওয়া ভিজিট এবং আপনার সাইটে cache থেকে পরিবেশন করা পেজ।
hosted product থেকে সরে আসার দিন মোট পরিসংখ্যানে পরিবর্তন আশা করুন এবং মনে রাখবেন এই পরিবর্তনের একটি অংশ ব্লক করার সাথে সম্পর্কিত নাও হতে পারে। pageview কী, single page application-এর ভেতরে route পরিবর্তনকে একটি pageview হিসেবে গণ্য করা হবে কি না, এবং কখন একটি session শেষ হয়—এসব বিষয়ে বিভিন্ন product-এর ভিন্ন ভিন্ন মত রয়েছে। ট্রাফিক কমেছে এমন সিদ্ধান্তে পৌঁছানোর আগে কয়েক সপ্তাহ ধরে ট্রেন্ডগুলো তুলনা করুন।
কোন সাইটের জন্য কোনটি উপযুক্ত
- ব্যক্তিগত সাইট বা ব্লগ যেখানে মাসে 50,000-এর কম পেজভিউ হয়: 1 GB VPS-এ GoatCounter বা Medama ব্যবহার করুন, যেখানে ব্যাকআপ হিসেবে ফাইল কপি রাখা যথেষ্ট।
- এমন সাইট যেখানে কোনো স্ক্রিপ্ট যোগ করা সম্ভব নয় বা ব্যবহারকারীরা কঠোরভাবে ট্র্যাকিং ব্লক করে: নিয়মিত বিরতিতে বিদ্যমান লগের ওপর GoAccess ব্যবহার করুন।
- ছোট ব্যবসার সাইট যেখানে অন্য কেউ ড্যাশবোর্ড পর্যবেক্ষণ করবে: Postgres কন্টেইনারসহ Umami ব্যবহার করুন।
- এমন সাইট যেখানে আপনি গোল (goals) এবং ফানেল (funnels) ট্র্যাক করতে চান এবং আপনার সার্ভারে 2 GB বা তার বেশি RAM আছে: Plausible Community Edition ব্যবহার করুন, অথবা যদি নতুন ড্যাশবোর্ড চান এবং অপেক্ষাকৃত নতুন প্রজেক্ট ব্যবহারে আপত্তি না থাকে তবে Rybbit বেছে নিন।
- অনেকগুলো সাইট, একাধিক ইউজার অ্যাকাউন্ট, অথবা নিজস্ব রিটেনশন পলিসি অনুযায়ী র-ডেটা (raw data) সংরক্ষণ করার প্রয়োজন হলে: Matomo ব্যবহার করুন, যা এর প্রকাশিত নির্দেশিকা অনুযায়ী কনফিগার করতে হবে।
আপনার প্রকৃত প্রয়োজন মেটাতে পারে এমন সবচেয়ে ছোট টুলটি দিয়ে শুরু করুন। পরবর্তীতে GoatCounter থেকে Plausible-এ স্থানান্তরিত হলে কেবল একটি সাবডোমেইন এবং কিছু পুরনো হিস্ট্রি হারানোর ঝুঁকি থাকে। কিন্তু Matomo থেকে অন্য কোনো টুলে স্থানান্তর করা বেশ জটিল একটি প্রক্রিয়া, যা আপনি উপভোগ করবেন না। একই সার্ভারে আর কী কী রাখা যায় তা নিয়ে যদি এখনো সিদ্ধান্ত না নিয়ে থাকেন, তবে the wider self-hosting roundup-এ এর পাশাপাশি কী কী রাখা যায় তা আলোচনা করা হয়েছে। আর যদি আপনার ভিজিটর সংখ্যার চেয়ে অ্যাপ্লিকেশনের রিকোয়েস্ট লেভেল ট্রেসিং বেশি প্রয়োজন হয়, তবে a self-hosted observability service আপনার জন্য সঠিক টুল।
FAQ
সেলফ-হোস্টেড অ্যানালিটিক্স ব্যবহার করলে কি কুকি ব্যানার সরানোর সুযোগ আছে?
না, এবং এই দুটি বিষয় সম্পূর্ণ আলাদা। ePrivacy-এর অধীনে সম্মতি বা consent-এর নিয়মটি ভিজিটরের ডিভাইসে কোনো কিছু সংরক্ষণ বা পড়ার ওপর প্রযোজ্য। তাই যে টুল কোনো কুকি সেট করে না এবং লোকাল স্টোরেজে কিছু লেখে না, সেটি এই নির্দিষ্ট প্রয়োজনীয়তার আওতার বাইরে থাকে। GDPR একটি ভিন্ন নিয়ম এবং এটি ব্যক্তিগত ডেটা প্রসেস করার ওপর প্রযোজ্য। যেহেতু IP অ্যাড্রেস ব্যক্তিগত ডেটা, তাই কুকি না থাকলেও আপনার একটি বৈধ ভিত্তি এবং ডেটা সংরক্ষণের সময়সীমা নির্ধারণ করতে হবে। সেলফ-হোস্টিংয়ের মাধ্যমে ডেটা আপনার সার্ভারে চলে আসে এবং এর দায়ভার আপনার ওপর বর্তায়। আপনার অঞ্চলের নিয়ন্ত্রক সংস্থার নির্দেশনা দেখুন এবং আপনার নির্দিষ্ট পরিস্থিতির জন্য একজন আইনজীবীর পরামর্শ নিন।
একটি VPS-এ সেলফ-হোস্টেড অ্যানালিটিক্সের জন্য কতটুকু RAM প্রয়োজন?
ড্যাশবোর্ড নয়, বরং ডেটাস্টোরই এটি নির্ধারণ করে। GoatCounter এবং Medama একটি ফাইলের ওপর একটি প্রসেস হিসেবে চলে এবং Medama-এর ডকুমেন্টেশন অনুযায়ী ছোট সাইটগুলো 256 MB RAM-এর মেশিনে চলতে পারে। Umami একটি Node অ্যাপ্লিকেশনের পাশাপাশি একটি Postgres কন্টেইনার যোগ করে। Plausible Community Edition এবং Rybbit উভয়ই ClickHouse ব্যবহার করে এবং উভয় প্রজেক্টই অন্তত 2 GB RAM-এর কথা উল্লেখ করে। Matomo-এর নিজস্ব নির্দেশনা অনুযায়ী মাসে 1,00,000 পেজভিউয়ের জন্য 2 CPU কোর এবং 2 GB RAM প্রয়োজন।
আমার সেলফ-হোস্টেড অ্যানালিটিক্সের সংখ্যা কেন আগের অ্যানালিটিক্সের চেয়ে কম দেখাচ্ছে?
এর দুটি কারণ রয়েছে এবং উভয়ই বাস্তব। ফিল্টার লিস্ট কিছু কালেক্টর রিকোয়েস্ট ব্লক করে দেয়, তাই স্ক্রিপ্ট-ভিত্তিক প্রতিটি টুলই সেই ভিজিটগুলো হারায়। এছাড়া প্রতিটি প্রোডাক্ট ভিন্নভাবে গণনা করে, কারণ পেজভিউ কী এবং সেশন কখন শেষ হয়—এই সংজ্ঞাগুলো তাদের মধ্যে ভিন্ন হতে পারে। আপনার অ্যাক্সেস লগ থেকে এক সপ্তাহের HTML পেজ রিকোয়েস্ট এবং স্ক্রিপ্ট-ভিত্তিক পেজভিউয়ের তুলনা করে দেখুন। এই পার্থক্যের কারণ হলো ব্লক হওয়া ভিজিট এবং ক্যাশ করা পেজ, যা অন্য কারো প্রকাশিত হারের ওপর নির্ভর না করে আপনার নিজের সাইট থেকেই পরিমাপ করা হয়েছে।
আমি কি ARM VPS-এ Plausible বা Rybbit চালাতে পারব?
উভয়ই ClickHouse ব্যবহার করে এবং ClickHouse-এর জন্য x86-এ SSE 4.2 অথবা ARM-এ NEON প্রয়োজন। Plausible-এর প্রয়োজনীয়তায় এটি স্পষ্টভাবে বলা আছে এবং Rybbit-এর ডক অনুযায়ী ARM সিস্টেমের জন্য ARMv8.2-A বা তার চেয়ে নতুন সংস্করণ প্রয়োজন। বর্তমানের ARM সার্ভার কোরগুলো এই মানদণ্ড পূরণ করে, কিন্তু পুরনো মডেলগুলো তা করে না। এক্ষেত্রে অ্যাপ্লিকেশন লগে কোনো ত্রুটি না দেখিয়ে ClickHouse ইন্সট্রাকশন সেট এরর (instruction set error) দেখিয়ে চালু হতে অস্বীকৃতি জানাবে। ছোট ARM বক্সে সিঙ্গেল-ফাইল টুলগুলো ব্যবহার করলে এই সমস্যার সম্মুখীন হতে হয় না, কারণ সেগুলোর কোনোটিই ClickHouse ব্যবহার করে না।
ট্র্যাকিং স্ক্রিপ্ট ব্যবহার না করে আমার কি সার্ভার লগ পার্স (parse) করা উচিত?
যখন আপনি স্ক্রিপ্ট যোগ করতে পারেন না, যখন আপনার অডিয়েন্স ব্যাপকভাবে ট্র্যাকিং ব্লক করে, অথবা যখন আপনি ক্রলারসহ মোট ভিজিটর সংখ্যা জানতে চান, তখন লগ পার্সিং ব্যবহার করুন। GoAccess আপনার সার্ভারের তৈরি করা লগ ফাইলটি পড়ে, তাই এটি পেজের লোড বাড়ায় না এবং কোনো ডেটাবেসও প্রয়োজন হয় না। তবে এক্ষেত্রে ব্রাউজারের ভেতরে যা ঘটে তা আপনি জানতে পারবেন না। এছাড়া CDN বা ব্রাউজার ক্যাশ থেকে সার্ভ হওয়া কোনো পেজও আপনি মিস করবেন, কারণ সেই রিকোয়েস্ট আপনার সার্ভার পর্যন্ত পৌঁছায় না। অনেক সাইটই উভয় পদ্ধতি ব্যবহার করে এবং সেগুলোকে দুটি ভিন্ন পরিমাপ হিসেবে গণ্য করে।