เลือกเครื่องมือวิเคราะห์เว็บ Self-hosted บน VPS ตัวไหนดี
เปรียบเทียบการติดตั้ง Plausible, Umami, Matomo, GoatCounter และ GoAccess บน VPS วิเคราะห์การใช้ RAM การเลือกฐานข้อมูล การจัดการ Log และข้อจำกัดเมื่อถูก Ad blocker บล็อก
เครื่องมือวิเคราะห์เว็บแบบ self-hosted ตัวใดที่ควรใช้งานบน VPS?
เครื่องมือวิเคราะห์เว็บแบบ self-hosted แบ่งออกเป็น 2 ประเภทหลัก การเลือกประเภทที่ผิดจะส่งผลกระทบมากกว่าการเลือกผลิตภัณฑ์ผิด ประเภทแรกจะรันสคริปต์ขนาดเล็กในเบราว์เซอร์ของผู้เข้าชมและจัดเก็บข้อมูลที่สคริปต์นั้นรายงาน ประเภทที่สองจะอ่านจาก access log ที่เว็บเซิร์ฟเวอร์ของคุณเขียนไว้อยู่แล้ว ทุกอย่างหลังจากนั้น รวมถึงฐานข้อมูลและหน่วยความจำที่ต้องใช้ จะขึ้นอยู่กับการตัดสินใจเลือกประเภทนี้
คำตอบสั้นๆ สำหรับเซิร์ฟเวอร์ขนาดเล็ก: GoatCounter และ Medama สามารถรันบน RAM 1 GB ได้ เนื่องจากแต่ละตัวเป็นเพียงหนึ่งโพรเซสที่ทำงานกับไฟล์เดียว ส่วน Umami จะเพิ่มคอนเทนเนอร์ Postgres เข้ามาและให้แดชบอร์ดที่ผู้ใช้งานทั่วไปสามารถอ่านค่าได้ง่าย สำหรับ Plausible Community Edition และ Rybbit ทั้งคู่ต้องใช้ ClickHouse ดังนั้นควรเตรียม RAM ไว้ 2 GB ขึ้นไป Matomo เป็นผลิตภัณฑ์เต็มรูปแบบและต้องการเซิร์ฟเวอร์ที่มีขนาดเหมาะสมกับปริมาณ traffic ของคุณ ในขณะที่ GoAccess ไม่เพิ่มภาระใดๆ ให้กับหน้าเว็บเลย เพราะมันทำหน้าที่อ่าน log ที่มีอยู่แล้วเท่านั้น
Script tag หรือ log ของเซิร์ฟเวอร์: สิ่งที่แต่ละวิธีมองเห็น
Script tag ทำหน้าที่วัดผลจากเบราว์เซอร์ เมื่อหน้าเว็บโหลดและสคริปต์ทำงาน มันจะส่งคำขอหนึ่งรายการไปยังตัวเก็บข้อมูล (collector) ของคุณ สิ่งใดก็ตามที่ทำให้ห่วงโซ่นี้ขาดหายไปจะทำให้คุณมองไม่เห็นข้อมูลนั้น เช่น การปิดใช้งาน JavaScript, รายการตัวกรองที่บล็อกคำขอ, คำขอไปยัง collector ล้มเหลว หรือ crawler ที่ไม่รันสคริปต์
Log parser ทำหน้าที่วัดผลจากคำขอ เว็บเซิร์ฟเวอร์ของคุณจะเขียน log หนึ่งบรรทัดต่อหนึ่งคำขอไม่ว่าคุณจะติดตั้งอะไรไว้หรือไม่ก็ตาม ดังนั้นข้อมูลจึงถูกจัดเก็บอยู่บนดิสก์อยู่แล้ว วิธีนี้จะมองเห็น crawler ทุกตัวและทุกการเข้าถึงไฟล์ที่ไม่มี script tag ติดตั้งอยู่ อย่างไรก็ตาม มันไม่สามารถมองเห็นสิ่งที่เกิดขึ้นภายในเบราว์เซอร์ และไม่สามารถมองเห็นหน้าเว็บที่ถูกเรียกจากแคชของเบราว์เซอร์หรือจาก CDN (content delivery network) ที่อยู่หน้าเซิร์ฟเวอร์ของคุณได้ เนื่องจากคำขอเหล่านั้นไม่เคยมาถึงเซิร์ฟเวอร์ของคุณ
ตัวเลขจากทั้งสองวิธีจะไม่ตรงกัน และไม่มีวิธีใดที่ผิด Matomo สามารถทำได้ทั้งสองอย่าง โดยมีการระบุข้อมูลที่การนำเข้า log (log import) จะสูญเสียไปเมื่อเทียบกับการใช้ JavaScript tracker ได้แก่ ความละเอียดหน้าจอ, ชื่อหน้าเว็บ, เหตุการณ์ต่างๆ (events), การติดตามเนื้อหา (content tracking), heatmap, การบันทึกเซสชัน (session recordings) และการวิเคราะห์ฟอร์ม (form analytics) รายการเหล่านี้คือสิ่งที่ต้องแลกมาเมื่อคุณเลือกนับจำนวนคำขอแทนการนับจำนวนเบราว์เซอร์
Traffic จากบอทคืออีกครึ่งหนึ่งของช่องว่างที่เกิดขึ้น การนับจาก log จะรวม crawler เข้าไปด้วยเว้นแต่คุณจะกรองออก ซึ่งในเว็บไซต์ทั่วไปสัดส่วนของ crawler นั้นมีมากพอที่จะทำให้ข้อสรุปของคุณคลาดเคลื่อนได้ ทั้ง GoAccess และการนำเข้า log ของ Matomo ต่างก็มีตัวกรองบอทที่รู้จักกันดี แต่ไม่มีวิธีใดที่สามารถกรอง crawler ที่ปลอมแปลง user agent ได้ ซึ่งเป็นเหตุผลที่ดีในการจับคู่การนับจาก log เข้ากับการ บล็อก AI crawler ที่ระดับเซิร์ฟเวอร์ และควรอ่าน log หลังจากทำการบล็อกแล้ว แทนที่จะอ่านก่อนการบล็อก
GoAccess: การวิเคราะห์จาก log ที่คุณมีอยู่แล้ว
ติดตั้งโปรแกรมจาก repository ของ Debian และ Ubuntu โดยตรง เนื่องจากแพ็กเกจที่มากับ distribution มักจะล้าหลังกว่าเวอร์ชันที่ปล่อยออกมาจริง
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จากนั้นระบุตำแหน่ง log และเขียนรายงานแบบ static
goaccess /var/log/nginx/access.log -o ~/report.html --log-format=COMBINEDคำสั่งดังกล่าวจะล้มเหลวด้วย Permission denied สำหรับผู้ใช้ทั่วไป เนื่องจากบน Ubuntu ไฟล์ log ของ nginx จะถูกครอบครองโดย root และมีกลุ่มเป็น adm ให้เพิ่มชื่อผู้ใช้ของคุณเข้าในกลุ่มนั้นด้วย sudo usermod -aG adm $USER จากนั้นให้ log out และ log in ใหม่ เนื่องจากระบบจะอ่านข้อมูลการเป็นสมาชิกกลุ่มเฉพาะตอน log in เท่านั้น ให้รัน id และตรวจสอบว่า adm ปรากฏอยู่ในรายการก่อนที่จะลองใหม่อีกครั้ง
รายงานจาก log แบบสดจะครอบคลุมเฉพาะข้อมูลที่ logrotate ยังไม่ได้ย้ายไปเท่านั้น คำขอของเมื่อวานจะอยู่ใน access.log.1 และไฟล์ที่เก่ากว่านั้นจะถูกบีบอัดไว้ ดังนั้นการดูรายงานรายสัปดาห์จึงจำเป็นต้องอ่านไฟล์ที่ถูก rotate ไปแล้วด้วย
zcat /var/log/nginx/access.log.*.gz | goaccess - --log-format=COMBINED -o ~/last-week.htmlนอกจากนี้ยังมีโหมดแสดงผลสดคือ --real-time-html ซึ่งจะอัปเดตหน้าเว็บผ่าน WebSocket วิธีนี้ต้องใช้พอร์ตที่สองและกฎ proxy แยกต่างหาก สำหรับเว็บไซต์ส่วนใหญ่ การเขียนรายงานรายชั่วโมงด้วย cron นั้นเพียงพอแล้วและมีความเสี่ยงด้านความปลอดภัยน้อยกว่า
GoatCounter: หนึ่ง Go binary และหนึ่งไฟล์ SQLite
GoatCounter ถูกจัดส่งในรูปแบบ binary ที่คอมไพล์แบบ static จึงไม่มี runtime ที่ต้องติดตั้ง คุณสามารถดาวน์โหลด build จากหน้า release แล้วเรียกใช้งานได้ทันที หรือจะใช้ image ก็ได้
docker run -p 8080:8080 -v goatcounter-data:/home/goatcounter/goatcounter-data arp242/goatcounterเมื่อรันเป็น binary ตัว goatcounter serve จะฟังการเชื่อมต่อที่พอร์ต 8080 และสร้างไฟล์ SQLite ไว้ที่ ./goatcounter-data/db.sqlite3 ให้สร้างไซต์แรกผ่าน command line แทนการใช้ web wizard ในกรณีที่ instance ของคุณอยู่หลัง proxy แล้ว
goatcounter db create site -vhost=stats.example.com -user.email=me@example.comตัวโปรแกรมสามารถจัดการ certificate ของตนเองได้ด้วย goatcounter serve -listen=:443 -tls=tls,rdr,acme โดยใช้ ACME (automatic certificate management environment) ซึ่งมีประโยชน์สำหรับเครื่องที่ไม่ได้รันบริการอื่น ในกรณีที่ nginx หรือ Caddy ครอบครองพอร์ต 443 อยู่แล้ว ให้ปล่อยให้ GoatCounter ทำงานที่พอร์ต 8080 และทำ proxy ส่งต่อคำขอไปยังพอร์ตดังกล่าวแทน สคริปต์ติดตามมีขนาดประมาณ 3.5K ตามข้อมูลของโครงการ และยังมี tracking pixel สำหรับหน้าเว็บที่ไม่ได้ใช้ JavaScript หาก SQLite กลายเป็นข้อจำกัดสำหรับไซต์ที่มีการใช้งานสูง ตัว binary เดียวกันนี้สามารถรองรับ Postgres ได้ด้วย goatcounter serve -db 'postgresql+dbname=goatcounter' การสำรองข้อมูลทำได้โดยการคัดลอกไฟล์ ซึ่งถือเป็นข้อได้เปรียบหลักของเครื่องมือในรูปแบบนี้
Medama: คอนเทนเนอร์เดี่ยวที่ใช้หน่วยความจำ 256 MB
Medama เป็นตัวเลือกแบบ single binary ล่าสุดในกลุ่มนี้ โดยถูกออกแบบมาให้ไม่ใช้คุกกี้ (cookie free) และทางโครงการระบุว่าตัวติดตามมีขนาดเล็กกว่า 1 KB อีกทั้งยังรองรับเว็บไซต์ขนาดเล็กที่รันบนเครื่องเสมือน (virtual machine) ที่มีหน่วยความจำ 256 MB นี่เป็นเพียงข้อมูลที่ทางโครงการเผยแพร่ ไม่ใช่ตัวเลขที่วัดผลสำหรับการทำคู่มือนี้
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 การใช้ prefix ของ loopback ในคำสั่งข้างต้นนั้นเป็นความตั้งใจ ซึ่งส่วนของ reverse proxy จะอธิบายเหตุผลไว้ การเข้าสู่ระบบครั้งแรกใช้ admin ด้วยรหัสผ่าน CHANGE_ME_ON_FIRST_LOGIN โดยชื่อของรหัสผ่านนั้นคือคำแนะนำในการใช้งาน
มีรูปแบบความล้มเหลวที่ระบุไว้ในเอกสารซึ่งคุณควรระวัง การเข้าสู่ระบบจะทำงานได้เฉพาะผ่าน HTTPS หรือบน localhost เท่านั้น ดังนั้นหากคุณตั้งค่า proxy ก่อนที่จะมีใบรับรอง (certificate) ฟอร์มจะปฏิเสธรหัสผ่านที่ถูกต้องโดยไม่แสดงเหตุผลให้ทราบ ให้ดำเนินการตั้งค่า TLS (transport layer security) ให้เสร็จสิ้นก่อน แล้วจึงค่อยเข้าสู่ระบบ
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 หรือใหม่กว่าหากคุณทำการ build จาก source ทั้งนี้มีอิมเมจที่ build ไว้ล่วงหน้าคือ docker.umami.is/umami-software/umami:postgresql-latest ซึ่งจำเป็นต้องใช้ DATABASE_URL เพื่อชี้ไปยังฐานข้อมูลที่คุณใช้งานอยู่แล้ว
การเข้าสู่ระบบครั้งแรกใช้ admin ด้วยรหัสผ่าน umami ให้เปลี่ยนรหัสผ่านทันทีก่อนที่จะชี้ DNS มายังเซิร์ฟเวอร์ เนื่องจาก instance จะสามารถเข้าถึงได้จากอินเทอร์เน็ตทันทีที่ record มีผลและ proxy ตอบรับคำขอ สำหรับรายละเอียดเกี่ยวกับ Compose, ไฟล์ environment และนโยบายการ restart โปรดดูที่ Docker Compose stack บน VPS แทนการคัดลอก stack ที่คุณยังไม่ได้อ่านรายละเอียด
การใช้ทรัพยากรประกอบด้วยกระบวนการ Node หนึ่งรายการและ Postgres ซึ่งถือว่าใช้ทรัพยากรมากกว่าการรันไฟล์ binary เพียงไฟล์เดียว แต่เบากว่าการรันระบบใดๆ ที่ใช้ 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เวอร์ชัน v3.2.1 เป็นเวอร์ชันปัจจุบัน ณ เดือนสิงหาคม 2026 และคำสั่ง clone ได้ระบุเวอร์ชันนี้ไว้โดยเฉพาะ สแต็กประกอบด้วยสามส่วน ได้แก่ ตัวแอปพลิเคชัน, Postgres สำหรับบัญชีและการตั้งค่า และ ClickHouse สำหรับข้อมูลเหตุการณ์ SECRET_KEY_BASE จะต้องมีความยาวอย่างน้อย 64 ไบต์ ซึ่งเป็นสิ่งที่คำสั่ง openssl สร้างขึ้น
ข้อกำหนดของ Plausible ต้องการ RAM อย่างน้อย 2 GB เพื่อป้องกันไม่ให้ ClickHouse และตัวแอปพลิเคชันถูก out of memory killer สั่งยุติการทำงาน และต้องการ CPU ที่รองรับชุดคำสั่ง SSE 4.2 หรือ NEON ซึ่ง ClickHouse จำเป็นต้องใช้ ข้อกำหนดประการที่สองนี้ควรตรวจสอบก่อนตัดสินใจซื้อ และเป็นหนึ่งในความแตกต่างเชิงปฏิบัติในการ เลือกระหว่าง ARM และ x86 VPS นอกจากนี้ ClickHouse จะใช้หน่วยความจำเท่าที่มันมองเห็นว่าว่างอยู่ ดังนั้นหากใช้งานบนเซิร์ฟเวอร์ร่วม ควรตั้งค่าเพดานหน่วยความจำตามที่อธิบายไว้ใน การจำกัดหน่วยความจำคอนเทนเนอร์ใน Compose
BASE_URL จะต้องตรงกับ public URL ทุกประการ หากไม่ตรงกัน เมื่อคุณเข้าสู่ระบบ แอปจะเปลี่ยนเส้นทางไปยังโฮสต์ที่ผิด และ session cookie จะถูกเขียนลงในโดเมนที่เบราว์เซอร์ของคุณไม่ได้ใช้งานอยู่ ส่งผลให้คุณถูกดีดกลับมาที่หน้าเข้าสู่ระบบโดยไม่มีข้อความแจ้งเตือนใดๆ
ไฟล์ compose ที่ให้มาไม่ได้เปิดพอร์ตไว้ เนื่องจากคาดว่าจะมีการใช้พร็อกซีอยู่ด้านหน้า ให้เพิ่มไฟล์ override เพื่อเปิดพอร์ตแอปพลิเคชันเริ่มต้นบน loopback เท่านั้น
cat > compose.override.yml << EOF
services:
plausible:
ports:
- 127.0.0.1:8000:8000
EOFMatomo: ตัวผลิตภัณฑ์เต็มรูปแบบและเซิร์ฟเวอร์ที่ต้องการ
Matomo ทำงานบน PHP ร่วมกับ MySQL หรือ MariaDB ซึ่งหมายความว่ามันเหมาะกับ stack เว็บแบบดั้งเดิมมากกว่า container stack นอกจากนี้ยังเป็นเครื่องมือเดียวในที่นี้ที่เผยแพร่คำแนะนำด้านฮาร์ดแวร์ตามปริมาณการใช้งาน
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
}
]ตัวเลขเหล่านี้คือค่าขั้นต่ำที่ Matomo เผยแพร่ ณ เดือนสิงหาคม 2026 ไม่ใช่การวัดผลที่ทำขึ้นสำหรับคู่มือนี้ สำหรับยอดเข้าชมสูงสุด 100,000 ครั้งต่อเดือน Matomo ต้องการ CPU 2 คอร์, RAM 2 GB และ SSD 50 GB โดยใช้เซิร์ฟเวอร์เครื่องเดียวสำหรับทั้งแอปพลิเคชันและฐานข้อมูล ที่ระดับ 1M/month ความต้องการจะเพิ่มเป็น RAM 8 GB และดิสก์ 250 GB ที่ระดับ 10M/month Matomo แนะนำให้ใช้เซิร์ฟเวอร์สองเครื่อง โดยแถวสุดท้ายแสดงสเปกของเซิร์ฟเวอร์ฐานข้อมูลคือ RAM 16 GB และดิสก์ 400 GB ให้เปรียบเทียบตัวเลขดิสก์เหล่านี้กับตัวเลือกแบบ binary เดี่ยว ซึ่งชุดข้อมูลทั้งหมดจะถูกเก็บไว้ในไฟล์ SQLite เพียงไฟล์เดียว
กระบวนการ archiving คือสิ่งที่ทำให้ผู้ใช้ประหลาดใจ โดยปกติแล้ว Matomo จะสร้างรายงานเมื่อมีคนเปิดหน้า dashboard ดังนั้นเมื่อข้อมูลมีขนาดใหญ่ขึ้น dashboard จะทำงานช้าลงและหมดเวลา (timeout) ในที่สุด วิธีแก้ไขที่ระบุไว้ในเอกสารคือให้ปิดการทำ archiving ผ่านเบราว์เซอร์ในการตั้งค่าทั่วไป แล้วเรียกใช้งาน archiver ผ่าน cron แทน โดยรันในฐานะผู้ใช้ที่เป็นเจ้าของไฟล์ Matomo จากภายในไดเรกทอรีของ Matomo
php console core:archive --url=https://analytics.example.comMatomo ยังคงเก็บตาราง log ดิบไว้ควบคู่กับตารางรายงานที่ประมวลผลแล้ว และสามารถตั้งเวลาลบข้อมูลดิบและรายงานเก่าได้ ให้เปิดใช้งานฟังก์ชันนี้ตั้งแต่ตอนติดตั้ง ไม่ใช่รอจนกว่าดิสก์จะเต็ม นอกจากนี้ Matomo ยังสามารถนำเข้า server access log ได้ ซึ่งทำให้มันเป็นผลิตภัณฑ์เดียวในที่นี้ที่ครอบคลุมทั้งสองรูปแบบพร้อมกัน
Rybbit และสแต็กใหม่ๆ
git clone https://github.com/rybbit-io/rybbit.git
cd rybbit
chmod +x *.sh
./setup.sh your.domain.nameRybbit เป็นซอฟต์แวร์ที่เพิ่งเปิดตัวมาพร้อมกับแดชบอร์ดที่ทันสมัย สคริปต์การติดตั้งจะเขียนไฟล์ environment และเริ่มการทำงานของสแต็กด้วย Docker Compose โดยมีการรัน ClickHouse และมาพร้อมกับ Caddy ในฐานะเว็บเซิร์ฟเวอร์ของตัวเอง ซึ่งจะเข้าใช้งานพอร์ต 443 และร้องขอใบรับรองสำหรับโดเมนที่คุณระบุ หากบนเซิร์ฟเวอร์มี nginx ใช้งานพอร์ต 443 อยู่แล้ว สคริปต์จะไม่สามารถ bind พอร์ตได้ ดังนั้นให้ใช้วิธีการรัน Compose แบบ manual ของโปรเจกต์และนำไปวางไว้หลัง proxy ที่คุณมีอยู่เดิม เอกสารระบุว่าต้องการ RAM อย่างน้อย 2 GB โดยผ่านการทดสอบบน Ubuntu 24 LTS และต้องใช้สถาปัตยกรรม ARMv8.2-A หรือใหม่กว่าสำหรับ ARM เนื่องจากข้อกำหนดของ ClickHouse
ข้อควรระวังสำหรับโปรเจกต์ใหม่คือ ฟีเจอร์ต่างๆ ถูกเพิ่มเข้ามาอย่างรวดเร็วและอาจมีการเปลี่ยนแปลงที่ส่งผลกระทบต่อระบบเดิม (breaking changes) ได้ง่าย ควรล็อกเวอร์ชันด้วย tag อ่านบันทึกการเปลี่ยนแปลง (release notes) ก่อนทำการ pull และสำรองข้อมูลฐานข้อมูลไว้ก่อนเสมอ
การเก็บรักษาข้อมูลและการเพิ่มขึ้นของขนาดดิสก์: การวัดผลบนเซิร์ฟเวอร์ของคุณเอง
การเพิ่มขึ้นของขนาดดิสก์ขึ้นอยู่กับสิ่งที่เครื่องมือจัดเก็บต่อเหตุการณ์ GoatCounter จะรวมยอดการเข้าชมเป็นตัวนับ ดังนั้นไฟล์จึงขยายตัวตามจำนวนหน้าและวันที่ที่ไม่ซ้ำกันมากกว่าปริมาณข้อมูลดิบ ส่วน Umami และ Matomo จะจัดเก็บข้อมูลเป็นแถวต่อเหตุการณ์ โดย Matomo จะจัดเก็บตารางรายงานที่ประมวลผลแล้วเพิ่มเติมจากข้อมูลดิบ ClickHouse จะจัดเก็บเหตุการณ์ในรูปแบบคอลัมน์และบีบอัดข้อมูลอย่างแน่นหนา ซึ่งเป็นเหตุผลที่ Plausible สามารถรองรับปริมาณข้อมูลที่อาจทำให้ฐานข้อมูลแบบแถวทั่วไปทำงานหนักเกินไป
คู่มือนี้ไม่ได้ระบุตัวเลขจำนวนเมกะไบต์ต่อการเข้าชมหนึ่งล้านครั้ง เนื่องจากไม่ได้วัดผลจากปริมาณการใช้งานของคุณ ให้คุณทำการวัดด้วยตนเอง โดยปรับชื่อบริการและชื่อผู้ใช้ให้ตรงกับไฟล์ Compose ของคุณ
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"ให้บันทึกตัวเลขไว้ รอหนึ่งสัปดาห์ แล้วบันทึกอีกครั้ง จากนั้นนำผลต่างที่ได้หารด้วยจำนวนการเข้าชมที่แดชบอร์ดรายงานสำหรับสัปดาห์นั้น ตัวเลขดังกล่าวจะสะท้อนถึงเว็บไซต์และการกรองบอทของคุณ ซึ่งมีค่ามากกว่าค่าเฉลี่ยที่เผยแพร่ทั่วไป จากนั้นให้กำหนดขีดจำกัดการเก็บรักษาข้อมูลในขณะที่ขนาดข้อมูลยังน้อยอยู่ หากดิสก์เต็มจะทำให้ทุกบริการบน VPS หยุดทำงาน ไม่ใช่แค่ระบบวิเคราะห์ข้อมูลเท่านั้น ซึ่งเป็นเหตุผลสำคัญที่สุดในการจัดเก็บ volume ของฐานข้อมูลไว้ในตำแหน่งที่ df -h จะแจ้งเตือนคุณได้ ความเสี่ยงนี้ควรได้รับความสนใจมากขึ้นบนเซิร์ฟเวอร์ที่มีข้อมูลขนาดใหญ่อยู่แล้ว เพราะ เซิร์ฟเวอร์รูปภาพแบบ self-hosted จะทำให้ดิสก์เต็มก่อนที่ฐานข้อมูลวิเคราะห์ใดๆ จะมีขนาดใกล้เคียงกัน
พฤติกรรมเมื่อทำงานอยู่หลัง reverse proxy บน subdomain
ให้ติดตั้งตัวเก็บข้อมูล (collector) ไว้บน subdomain ของเว็บไซต์ที่ต้องการวัดผล เช่น stats.example.com วิธีนี้จะทำให้คำขอของ collector กลายเป็น first party ซึ่งจะไม่ถูกกฎของเบราว์เซอร์ที่บล็อกคำขอ third party ขัดขวาง
ผูกแอปพลิเคชันกับ loopback เมื่อเผยแพร่พอร์ตของ container Docker จะเขียนกฎ firewall ของตนเองไว้ก่อน ufw ดังนั้น container ที่เผยแพร่เป็น -p 3000:3000 จึงเข้าถึงได้จากอินเทอร์เน็ต แม้ ufw status จะแจ้งว่าพอร์ตถูกปฏิเสธ ทดสอบจากเครื่องอื่นด้วย curl http://SERVER_IP:3000 แล้วจะได้รับ dashboard หากเผยแพร่เป็น -p 127.0.0.1:3000:3000 การทดสอบเดียวกันจะได้ Connection refused และมีเพียง proxy เท่านั้นที่เข้าถึงได้ แนวทางเดียวกันนี้ไม่ได้มีไว้เพื่อซ่อน dashboard เท่านั้น แต่เป็นพื้นฐานของ การรัน onion service บนเครื่องเดียวกัน ซึ่ง service ใดก็ตามที่ยังตอบสนองบน public interface จะเป็นสิ่งที่เชื่อม hidden address กลับมายัง IP ของคุณ endpoint ของ collector ต้องยังเข้าถึงได้จากอินเทอร์เน็ตสาธารณะ แต่ dashboard ไม่จำเป็นต้องทำเช่นนั้น และหากต้องการอ่าน dashboard ผ่าน private network แทนการเผยแพร่ subdomain ที่สอง การประกาศเครือข่ายของ VPS ไปยัง tailnet ด้วย subnet router จะช่วยให้เข้าถึงได้โดยไม่ต้องเปิดพอร์ต נוספת
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;
}
}header สำหรับการส่งต่อ (forwarding headers) เป็นสิ่งที่ขาดไม่ได้ในกรณีนี้ หากไม่มี X-Forwarded-For การเข้าชมทุกครั้งจะปรากฏว่ามาจาก 127.0.0.1 ส่งผลให้รายงานตามประเทศว่างเปล่าและจำนวนผู้เข้าชมที่ไม่ซ้ำกัน (unique visitors) จะถูกนับรวมเหลือเพียงหนึ่งเดียว แต่ละโปรเจกต์จะกำหนดเองว่าเชื่อถือ header ใดและภายใต้การตั้งค่าแบบใด ดังนั้นควรตรวจสอบเอกสารประกอบของ proxy สำหรับโปรเจกต์นั้นๆ แทนการคาดเดา Caddy จะตั้งค่า header เหล่านี้ให้โดยอัตโนมัติ และ Caddyfile สำหรับงานเดียวกันนี้ใช้เพียงสองบรรทัดเท่านั้น
stats.example.com {
reverse_proxy 127.0.0.1:3000
}หากคุณยังไม่ได้เลือก proxy การเปรียบเทียบระหว่าง Nginx, Caddy และ Traefik จะช่วยให้คุณทราบว่าตัวเลือกใดเหมาะสมที่สุดสำหรับเซิร์ฟเวอร์เครื่องเดียวที่มี subdomain จำนวนไม่มาก
คุณยังจำเป็นต้องมีแถบแจ้งเตือนคุกกี้หรือไม่หากคุณโฮสต์บริการด้วยตนเอง
การโฮสต์บริการด้วยตนเอง (self-hosting) เปลี่ยนแปลงผู้ถือครองข้อมูล แต่ไม่ได้เปลี่ยนแปลงข้อกำหนดทางกฎหมายเกี่ยวกับข้อมูลนั้น โปรดแยกกฎสองข้อนี้ออกจากกัน กฎการให้ความยินยอมตาม ePrivacy เกี่ยวข้องกับการจัดเก็บหรืออ่านข้อมูลใดๆ บนอุปกรณ์ของผู้เข้าชม ดังนั้นเครื่องมือที่ไม่ตั้งค่าคุกกี้และไม่เขียนข้อมูลใดๆ ลงใน local storage จึงอยู่นอกเหนือข้อกำหนดเฉพาะส่วนนี้ ส่วน GDPR เกี่ยวข้องกับการประมวลผลข้อมูลส่วนบุคคล และที่อยู่ IP ถือเป็นข้อมูลส่วนบุคคล ดังนั้นคุณยังคงต้องมีฐานทางกฎหมายในการประมวลผล มีการกำหนดระยะเวลาในการเก็บรักษาข้อมูล และมีคำตอบเมื่อมีผู้สอบถามว่าคุณจัดเก็บข้อมูลอะไรเกี่ยวกับพวกเขาไว้บ้าง
Plausible, Umami, GoatCounter และ Medama ไม่ตั้งค่าคุกกี้โดยค่าเริ่มต้น สิ่งที่แต่ละเครื่องมือใช้แทนนั้นแตกต่างกันไปตามแต่ละโปรเจกต์และมีการเปลี่ยนแปลงระหว่างเวอร์ชัน ดังนั้นโปรดอ่านเอกสารเกี่ยวกับความเป็นส่วนตัวของโปรเจกต์นั้นๆ โดยตรงแทนการอ่านสรุป Matomo มีฟีเจอร์การทำ IP anonymisation และ endpoint สำหรับการ opt-out ซึ่งคุณสามารถเปิดใช้งานได้ในหน้า admin
หน่วยงานกำกับดูแลในแต่ละประเทศมีข้อสรุปที่แตกต่างกัน ตัวอย่างเช่น CNIL ของฝรั่งเศสได้เผยแพร่เงื่อนไขที่การวัดผลผู้ชมอาจได้รับยกเว้นจากการขอความยินยอม ส่วนนี้เป็นเพียงสรุปข้อเท็จจริงไม่ใช่คำแนะนำทางกฎหมาย สำหรับเว็บไซต์จริงที่มีผู้ใช้งานจริง โปรดปรึกษาทนายความในเขตอำนาจศาลของคุณ
ประเด็นหนึ่งที่ผู้คนมักมองข้ามคือ access log ก็ถือเป็นข้อมูลส่วนบุคคลเช่นกัน GoAccess ไม่ได้เพิ่มสคริปต์ใดๆ ลงในหน้าเว็บ แต่ยังคงประมวลผลที่อยู่ IP ดังนั้นการวิเคราะห์ข้อมูลจาก log จึงไม่ได้อยู่นอกเหนือกฎระเบียบโดยอัตโนมัติ การย้ายบริการมาไว้บนเซิร์ฟเวอร์ของคุณเองเป็นการย้ายตำแหน่งความเสี่ยงมากกว่าการกำจัดความเสี่ยงนั้นทิ้งไป ซึ่งเป็นเหตุผลเดียวกันกับที่ สิ่งที่อินสแตนซ์ SearXNG ที่โฮสต์เองปกปิดจริงๆ สิ้นสุดลงที่ตัว search engine ในขณะที่คำค้นหายังคงถูกบันทึกอยู่ใน log ของคุณเอง
ตัวบล็อกโฆษณาและเหตุผลที่ตัวเลขของคุณจะลดลง
รายการตัวกรอง (filter lists) จะจับคู่กับชื่อโฮสต์และรูปแบบของ URL ผลิตภัณฑ์วิเคราะห์ข้อมูลแบบโฮสต์ (hosted analytics) นั้นตรวจจับได้ง่าย เพราะทุกคนโหลดข้อมูลจากชื่อโฮสต์ที่เป็นที่รู้จักเหมือนกันหมด การย้ายตัวเก็บข้อมูล (collector) ไปยังโดเมนย่อยของคุณเองจะช่วยลบชื่อโฮสต์นั้นออกจากการร้องขอ และการให้บริการสคริปต์จาก path ที่คุณเลือกเองจะช่วยลบชื่อไฟล์ที่เป็นที่รู้จักออกไป ทั้งสองวิธีนี้เปลี่ยนสิ่งที่รายการตัวกรองใช้ในการจับคู่
โพสต์นี้ไม่ได้ยืนยันอัตราการตรวจจับ (hit rate) เนื่องจากไม่ได้ทำการวัดผล สัดส่วนของผู้เข้าชมที่บล็อกการตั้งค่าใดการตั้งค่าหนึ่งนั้นขึ้นอยู่กับกลุ่มผู้ชมของคุณ โดยกลุ่มนักพัฒนาจะมีการบล็อกมากกว่ากลุ่มทั่วไปอย่างมาก ให้คุณวัดช่องว่างของข้อมูลด้วยตนเอง ในช่วงสัปดาห์เดียวกัน ให้คุณนับจำนวนการร้องขอหน้า HTML ใน access log ด้วย GoAccess แล้วนำไปเปรียบเทียบกับจำนวนการเข้าชมหน้าเว็บ (pageviews) ที่เครื่องมือแบบใช้สคริปต์ของคุณรายงาน ผลต่างที่ได้คือจำนวนการเข้าชมที่ถูกบล็อกรวมกับหน้าเว็บที่ถูกโหลดจากแคชบนเว็บไซต์ของคุณ
คาดการณ์ได้ว่ายอดรวมจะเปลี่ยนแปลงในวันที่คุณเปลี่ยนจากผลิตภัณฑ์แบบโฮสต์ และคาดการณ์ได้ว่าส่วนหนึ่งของการเปลี่ยนแปลงนั้นอาจไม่เกี่ยวข้องกับการบล็อกเลย ผลิตภัณฑ์แต่ละตัวมีนิยามของ pageview ที่ต่างกัน รวมถึงการนับว่าการเปลี่ยนเส้นทาง (route change) ภายในแอปพลิเคชันหน้าเดียว (single page application) นับเป็นหนึ่งครั้งหรือไม่ และเซสชันสิ้นสุดลงเมื่อใด ให้เปรียบเทียบแนวโน้มในแต่ละสัปดาห์ก่อนที่จะสรุปว่าปริมาณการเข้าชมลดลงจริง
เลือกเครื่องมือให้เหมาะกับเว็บไซต์
- เว็บไซต์ส่วนตัวหรือบล็อกที่มีผู้เข้าชมไม่เกิน 50,000 หน้าต่อเดือน: ใช้ GoatCounter หรือ Medama บน VPS ขนาด 1 GB โดยสำรองข้อมูลด้วยการคัดลอกไฟล์
- เว็บไซต์ที่ไม่สามารถเพิ่มสคริปต์ได้ หรือมีกลุ่มผู้เข้าชมที่บล็อกสคริปต์อย่างหนัก: ใช้ GoAccess วิเคราะห์จาก log ที่มีอยู่ตามกำหนดเวลา
- เว็บไซต์ธุรกิจขนาดเล็กที่ต้องการให้ผู้อื่นเข้าถึงแดชบอร์ดได้: ใช้ Umami ร่วมกับคอนเทนเนอร์ Postgres
- เว็บไซต์ที่ต้องการติดตามเป้าหมาย (goals) และเส้นทางของผู้ใช้ (funnels) บนเซิร์ฟเวอร์ที่มี RAM ตั้งแต่ 2 GB ขึ้นไป: ใช้ Plausible Community Edition หรือ Rybbit หากต้องการแดชบอร์ดรูปแบบใหม่และยอมรับการใช้งานโปรเจกต์ที่ยังใหม่กว่าได้
- เว็บไซต์จำนวนมาก, มีบัญชีผู้ใช้หลายระดับ หรือมีความจำเป็นต้องเก็บข้อมูลดิบภายใต้นโยบายการเก็บรักษาข้อมูลของคุณเอง: ใช้ Matomo โดยปรับขนาดตามคำแนะนำที่ระบุไว้ข้างต้น
ให้เริ่มต้นด้วยเครื่องมือที่เล็กที่สุดที่ตอบโจทย์ความต้องการของคุณ การย้ายจาก GoatCounter ไปยัง Plausible ในภายหลังจะทำให้คุณเสียซับโดเมนและประวัติข้อมูลบางส่วนไป แต่การย้ายจาก Matomo ไปยังเครื่องมืออื่นนั้นต้องผ่านกระบวนการย้ายข้อมูลที่ยุ่งยาก หากคุณยังตัดสินใจไม่ได้ว่าควรติดตั้งอะไรเพิ่มเติมบนเซิร์ฟเวอร์เดียวกัน บทสรุปการทำ self-hosting ในภาพรวม จะครอบคลุมถึงสิ่งที่สามารถติดตั้งควบคู่กันได้ และหากสิ่งที่คุณต้องการจริงๆ คือการติดตามคำขอในระดับแอปพลิเคชันแทนที่จะเป็นเพียงจำนวนผู้เข้าชม บริการ observability แบบ self-hosted คือเครื่องมือที่เหมาะสมสำหรับงานนั้นมากกว่า
FAQ
การทำ self-hosting ระบบวิเคราะห์ข้อมูลช่วยให้ไม่ต้องติดป้ายแจ้งเตือนคุกกี้ใช่หรือไม่
ไม่เกี่ยวกัน และทั้งสองเรื่องเป็นคนละประเด็น กฎการขอความยินยอมภายใต้ ePrivacy ครอบคลุมถึงการจัดเก็บหรืออ่านข้อมูลบนอุปกรณ์ของผู้เข้าชม ดังนั้นเครื่องมือที่ไม่สร้างคุกกี้และไม่เขียนข้อมูลลงใน local storage จึงไม่อยู่ในข้อกำหนดส่วนนี้ แต่ GDPR เป็นกฎอีกฉบับที่ครอบคลุมการประมวลผลข้อมูลส่วนบุคคล และ IP address ถือเป็นข้อมูลส่วนบุคคล ดังนั้นคุณยังคงต้องมีฐานทางกฎหมายและกำหนดระยะเวลาการเก็บรักษาข้อมูลแม้ว่าจะไม่มีคุกกี้ก็ตาม การทำ self-hosting เป็นการย้ายข้อมูลมาไว้บนเซิร์ฟเวอร์ของคุณและทำให้คุณเป็นผู้รับผิดชอบข้อมูลนั้นโดยตรง โปรดตรวจสอบคำแนะนำจากหน่วยงานกำกับดูแลในพื้นที่ของคุณและปรึกษาทนายความสำหรับกรณีของคุณ
ระบบวิเคราะห์ข้อมูลแบบ self-hosted ต้องการ RAM บน VPS เท่าใด
ตัวจัดเก็บข้อมูล (datastore) เป็นตัวกำหนด ไม่ใช่ตัว dashboard ของระบบ GoatCounter และ Medama ทำงานเป็น process เดียวบนไฟล์เดียว โดยเอกสารของ Medama ระบุว่าเว็บไซต์ขนาดเล็กสามารถรันบนเครื่องที่มี RAM 256 MB ได้ ส่วน Umami จะเพิ่ม container ของ Postgres ควบคู่ไปกับแอปพลิเคชัน Node สำหรับ Plausible Community Edition และ Rybbit ทั้งคู่ใช้ ClickHouse ซึ่งทั้งสองโครงการระบุว่าต้องการ RAM อย่างน้อย 2 GB ส่วนคำแนะนำของ Matomo เริ่มต้นที่ 2 CPU cores และ 2 GB ของ RAM สำหรับการเข้าชมสูงสุด 100,000 ครั้งต่อเดือน
ทำไมตัวเลขจากระบบ self-hosted ถึงต่ำกว่าระบบวิเคราะห์ข้อมูลเดิมที่เคยใช้
มีสองสาเหตุที่เป็นไปได้จริง ประการแรก รายการตัวกรอง (filter lists) จะบล็อกคำขอไปยังตัวเก็บข้อมูลบางรายการ ทำให้เครื่องมือที่ใช้สคริปต์ทุกตัวพลาดการนับการเข้าชมเหล่านั้น ประการที่สอง ผลิตภัณฑ์แต่ละตัวมีวิธีการนับที่ต่างกัน เนื่องจากนิยามของ pageview และจุดสิ้นสุดของ session ในแต่ละตัวไม่เหมือนกัน ให้ลองเปรียบเทียบจำนวนคำขอหน้า HTML จาก access log ของคุณในหนึ่งสัปดาห์กับจำนวน pageview จากสคริปต์ในสัปดาห์เดียวกัน ช่องว่างที่เกิดขึ้นคือจำนวนการเข้าชมที่ถูกบล็อกบวกกับหน้าเว็บที่ถูกแคชไว้ ซึ่งเป็นการวัดผลจากเว็บไซต์ของคุณเองแทนที่จะอ้างอิงจากอัตราเฉลี่ยของผู้อื่น
ฉันสามารถรัน Plausible หรือ Rybbit บน ARM VPS ได้หรือไม่
ทั้งสองตัวใช้ ClickHouse ซึ่ง ClickHouse ต้องการ SSE 4.2 บน x86 หรือ NEON บน ARM ข้อกำหนดของ Plausible ระบุไว้ชัดเจน และเอกสารของ Rybbit ระบุว่าระบบ ARM ต้องเป็น ARMv8.2-A หรือใหม่กว่า ARM server core ในปัจจุบันผ่านเกณฑ์นี้ แต่รุ่นเก่าจะไม่ผ่าน โดยความล้มเหลวจะแสดงในลักษณะที่ ClickHouse ปฏิเสธที่จะเริ่มทำงานเนื่องจากข้อผิดพลาดของชุดคำสั่ง (instruction set error) แทนที่จะเป็นข้อผิดพลาดใน log ของแอปพลิเคชัน สำหรับเครื่อง ARM ขนาดเล็ก เครื่องมือแบบไฟล์เดียวจะไม่มีปัญหานี้เพราะไม่มีตัวใดที่ใช้ ClickHouse
ฉันควรวิเคราะห์ server log แทนการใช้ tracking script หรือไม่
ให้ใช้การวิเคราะห์ log เมื่อคุณไม่สามารถเพิ่มสคริปต์ได้ เมื่อกลุ่มเป้าหมายของคุณมีการบล็อกสคริปต์อย่างหนัก หรือเมื่อคุณต้องการจำนวนการเข้าชมที่รวมถึง crawler ด้วย GoAccess จะอ่าน log ที่เซิร์ฟเวอร์ของคุณเขียนอยู่แล้ว จึงไม่เพิ่มภาระให้กับหน้าเว็บและไม่ต้องใช้ฐานข้อมูล แต่คุณจะสูญเสียข้อมูลทุกอย่างที่เกิดขึ้นภายในเบราว์เซอร์ และจะพลาดการนับหน้าเว็บที่ถูกส่งจาก CDN หรือจากแคชของเบราว์เซอร์ เพราะคำขอเหล่านั้นไม่เคยมาถึงเซิร์ฟเวอร์ของคุณ เว็บไซต์จำนวนมากเลือกใช้ทั้งสองวิธีและถือว่าเป็นการวัดผลสองรูปแบบที่แยกจากกัน