ติดตั้ง Umami Analytics บน VPS — วิเคราะห์เว็บ Privacy-First
Umami เป็น web analytics แบบ open-source ที่เน้น privacy-first — ไม่ใช้ cookies ไม่เก็บ personal data ของผู้เข้าชม และ GDPR compliant ตามค่าเริ่มต้น เหมาะมากสำหรับเจ้าของเว็บที่ต้องการ analytics ที่เชื่อถือได้โดยไม่ต้องพึ่ง Google Analytics
บทความนี้จะสอนติดตั้ง Umami บน VPS Ubuntu 22.04 ด้วย Docker Compose, Nginx reverse proxy และ SSL certificate จาก Let's Encrypt แบบ production-ready
ทำไมต้องใช้ Umami แทน Google Analytics?
| ฟีเจอร์ | Umami (self-hosted) | Google Analytics 4 |
|---|---|---|
| Privacy / GDPR | ✅ ไม่เก็บ personal data | ⚠️ ต้องการ consent banner |
| Cookies | ✅ ไม่ใช้ cookies | ❌ ใช้ cookies |
| ข้อมูลเป็นของคุณ | ✅ 100% | ❌ Google เก็บข้อมูล |
| ค่าใช้จ่าย | ✅ ฟรี (เสียแค่ VPS) | ✅ ฟรี (แต่แลกด้วยข้อมูล) |
| ความเร็ว script | ✅ <2KB | ❌ ~45KB+ |
| Ad blocker ผ่าน | ✅ host เองใน domain ตัวเอง | ❌ ถูก block บ่อย |
ความต้องการระบบ
- VPS Ubuntu 20.04 / 22.04 / 24.04 (RAM 512MB ขึ้นไป)
- Docker + Docker Compose ติดตั้งแล้ว
- Domain ชี้มาที่ VPS (เช่น
analytics.yourdomain.com) - Port 80/443 เปิดอยู่
ขั้นที่ 1 — ติดตั้ง Docker (ถ้ายังไม่มี)
sudo apt update && sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
| sudo tee /etc/apt/sources.list.d/docker.list
sudo apt update && sudo apt install -y docker-ce docker-compose-plugin
sudo usermod -aG docker $USER
usermod ให้ logout แล้ว login ใหม่เพื่อให้สิทธิ์ group มีผลขั้นที่ 2 — สร้าง Docker Compose สำหรับ Umami
mkdir -p /opt/umami && cd /opt/umami
สร้าง docker-compose.yml:
cat > docker-compose.yml <<'EOF'
version: '3'
services:
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
restart: unless-stopped
environment:
DATABASE_URL: postgresql://umami:umami_secure_pass@db:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: your_random_secret_here_32chars
depends_on:
- db
ports:
- "3000:3000"
db:
image: postgres:15-alpine
restart: unless-stopped
environment:
POSTGRES_DB: umami
POSTGRES_USER: umami
POSTGRES_PASSWORD: umami_secure_pass
volumes:
- umami_db:/var/lib/postgresql/data
volumes:
umami_db:
EOF
umami_secure_pass และ APP_SECRET เป็นค่าสุ่มจริง ใช้ openssl rand -base64 32 สร้างรหัสผ่านขั้นที่ 3 — สร้าง APP_SECRET และ DB password ที่ปลอดภัย
# สร้าง secret สุ่ม
DB_PASS=$(openssl rand -base64 24)
APP_SECRET=$(openssl rand -hex 32)
echo "DB_PASS: $DB_PASS"
echo "APP_SECRET: $APP_SECRET"
# แก้ค่าใน docker-compose.yml
sed -i "s/umami_secure_pass/$DB_PASS/g" docker-compose.yml
sed -i "s/your_random_secret_here_32chars/$APP_SECRET/" docker-compose.yml
ขั้นที่ 4 — รัน Umami
cd /opt/umami
docker compose up -d
# ดู logs
docker compose logs -f umami
รอสัก 30 วินาที Umami จะ initialize database แล้วฟัง port 3000
ขั้นที่ 5 — ตั้งค่า Nginx Reverse Proxy + SSL
sudo apt install -y nginx certbot python3-certbot-nginx
# สร้าง config
sudo tee /etc/nginx/sites-available/umami <<'EOF'
server {
listen 80;
server_name analytics.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
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;
proxy_cache_bypass $http_upgrade;
}
}
EOF
sudo ln -s /etc/nginx/sites-available/umami /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
# ขอ SSL
sudo certbot --nginx -d analytics.yourdomain.com
ขั้นที่ 6 — Login และตั้งค่าแรก
เปิดเบราว์เซอร์ไปที่ https://analytics.yourdomain.com
- Default username:
admin - Default password:
umami - เปลี่ยนรหัสผ่านทันทีหลัง login ครั้งแรก!
ขั้นที่ 7 — เพิ่มเว็บไซต์และฝัง Tracking Script
ใน Umami dashboard ไปที่ Settings → Websites → Add website แล้วก็อป tracking script ที่ได้ไปวางใน <head> ของเว็บ:
<script defer src="https://analytics.yourdomain.com/script.js"
data-website-id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"></script>
defer จึงไม่กระทบ Core Web Vitals ของเว็บขั้นที่ 8 — ตั้งค่า Auto-backup Database
# สร้าง backup script
cat > /opt/umami/backup.sh <<'EOF'
#!/bin/bash
BACKUP_DIR="/opt/umami/backups"
DATE=$(date +%Y%m%d_%H%M)
mkdir -p "$BACKUP_DIR"
docker exec umami-db-1 pg_dump -U umami umami | gzip > "$BACKUP_DIR/umami_$DATE.sql.gz"
# เก็บแค่ 14 วัน
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +14 -delete
EOF
chmod +x /opt/umami/backup.sh
# ตั้ง cron backup ทุกคืน 2:00
(crontab -l 2>/dev/null; echo "0 2 * * * /opt/umami/backup.sh") | crontab -
ตรวจสอบว่า Umami ทำงานถูกต้อง
# ดูสถานะ containers
docker compose -f /opt/umami/docker-compose.yml ps
# ตรวจสอบ Umami API
curl -s http://localhost:3000/api/heartbeat
# ควรได้: {"ok":true}
# ตรวจสอบ database connection
docker compose -f /opt/umami/docker-compose.yml exec db \
psql -U umami -c '\l'
# ดู logs errors
docker compose -f /opt/umami/docker-compose.yml logs --tail=50 umami
# ตรวจสอบ Nginx
sudo nginx -t && sudo systemctl status nginx
/api/heartbeat ตอบ {"ok":true} แสดงว่า Umami พร้อมรับ requests แล้ว ถ้า tracking script ยังไม่ส่ง event ลองเปิด browser DevTools ดู Network tab ว่า request ถึง Umami หรือเปล่าแก้ปัญหาที่พบบ่อย
Error: "Error: connect ECONNREFUSED 127.0.0.1:5432"
Umami หา database ไม่เจอ เกิดจาก container db ยังไม่พร้อม หรือชื่อ service ไม่ตรงกับใน DATABASE_URL
docker compose ps # ดูว่า db running
docker compose logs db # ดู postgres error
# แก้: รอสัก 30 วินาทีแล้ว restart
docker compose restart umami
Error: "invalid input syntax for type uuid"
APP_SECRET ไม่ตรงกับที่ใช้สร้าง session — เกิดเมื่อเปลี่ยน secret โดยไม่ clear session เก่า
# หน้า login → กด Ctrl+Shift+Delete ล้าง cookies แล้ว login ใหม่
# หรือ restart umami container
docker compose restart umami
Error: "502 Bad Gateway" จาก Nginx
Nginx ส่ง request ไปหา Umami ไม่ถึง อาจเพราะ container ยังไม่ขึ้น หรือ port ผิด
docker compose ps # ดู port mapping
curl -s http://localhost:3000 # ทดสอบ direct
sudo tail -f /var/log/nginx/error.log # ดู nginx error
Error: "ERR_TOO_MANY_REDIRECTS" บน HTTPS
Nginx ส่ง X-Forwarded-Proto ซ้ำกับ Umami config ทำให้ redirect loop
# ตรวจสอบ Nginx config
grep -n "X-Forwarded-Proto" /etc/nginx/sites-available/umami
# ต้องมีแค่บรรทัดเดียว: proxy_set_header X-Forwarded-Proto $scheme;
Script ถูก Ad Blocker บล็อก
ถ้า tracking script ชี้ที่ analytics.yourdomain.com มักไม่โดน block ต่างจาก Google Analytics แต่ถ้ายังโดนให้ลอง custom script path
# แก้ใน docker-compose.yml เพิ่ม environment
TRACKER_SCRIPT_NAME: track
คำถามที่พบบ่อย
Umami เก็บข้อมูลอะไรบ้าง?
Umami เก็บ URL ที่เยี่ยมชม, referrer, browser, OS, device type, country (จาก IP แต่ไม่เก็บ IP จริง) และ timestamp ไม่มีการเก็บ IP address จริง, cookies หรือ personal identifier ใดๆ ทำให้ compliant กับ GDPR, CCPA โดยอัตโนมัติ
รองรับ multiple websites ในบัญชีเดียวได้ไหม?
ได้เลย Umami รองรับการเพิ่มเว็บหลายแห่งในบัญชีเดียว โดยแต่ละเว็บจะได้ website-id ของตัวเอง สามารถ share dashboard ให้คนอื่น view-only ได้ด้วย
Umami กินทรัพยากรเท่าไหร่?
บน VPS RAM 1GB Umami + PostgreSQL ใช้ RAM ประมาณ 200-300MB รองรับเว็บที่มี pageviews หลักหมื่นต่อวันได้สบาย ถ้าต้องการรองรับ traffic สูงขึ้นให้เพิ่ม RAM หรือ upgrade PostgreSQL index