Kamu punya blog WordPress yang udah jalan, trafik mulai naik, dan sekarang pengin tau siapa aja yang mampir. Langkah paling gampang? Pasang Google Analytics. Tapi begitu dipasang, tiap pengunjung yang buka halaman kamu itu datanya dikirim dulu ke server Google, diproses di sana, baru muncul di dashboard. Browser pengunjung harus load script pihak ketiga, nyimpen cookie tracking, dan semua data kunjungan itu technically bukan milik kamu sepenuhnya – dia numpang di infrastruktur Google.
Buat blog personal atau tutorial yang lagi ngejar approval AdSense dan pengin keliatan bersih soal privasi, ini jadi poin yang worth dipikirin ulang. Apalagi regulasi kayak GDPR di Eropa udah mulai ketat soal cookie tracking pihak ketiga. Nah, gimana kalau ada cara buat dapetin data analitik yang sama pentingnya, tapi datanya gak pernah keluar dari server kamu sendiri?
Di sinilah Umami masuk. Umami adalah tool analitik web open source yang bisa kamu install sendiri di VPS, gak pakai cookie secara default, dan semua data tersimpan di database milik kamu. Artikel ini bakal nuntun kamu dari nol sampai Umami jalan dan nge-track pengunjung blog WordPress kamu – lengkap dengan penjelasan tiap langkah biar gak cuma copy-paste doang.
Apa Itu Umami dan Kenapa Cocok Buat Blog Self-Hosted
Umami adalah platform web analytics open source yang didesain sebagai alternatif ringan dari Google Analytics. Nama “Umami” sendiri diambil dari bahasa Jepang yang artinya “rasa gurih” – dan memang tool ini fokus ngasih data yang “berasa” tanpa embel-embel fitur yang gak kepake.
Cara kerjanya simpel: kamu taruh satu baris script tracking di halaman website, dan tiap kali ada pengunjung yang buka halaman itu, browser mereka ngirim data kunjungan langsung ke server Umami kamu – bukan ke server pihak ketiga. Data yang dikumpulin termasuk jumlah pageview, unique visitor, sumber trafik (referrer), negara asal, browser yang dipake, dan halaman mana yang paling sering dibuka.

Yang bikin Umami beda dari analitik mainstream:
- Gak pakai cookie – Umami mengidentifikasi visitor pakai kombinasi hash dari IP + user agent + salt harian, jadi gak perlu banner consent cookie
- Ringan banget – Script tracking-nya cuma sekitar 2KB (gzipped), jauh lebih kecil dari Google Analytics yang bisa 45KB+
- Dashboard satu halaman – Semua metrik penting langsung keliatan tanpa harus klik-klik menu berlapis
- Privacy-first – Gak ada data yang dikirim ke pihak ketiga, semua tersimpan di database kamu sendiri
- Self-hosted – Kamu punya kontrol penuh atas data dan infrastrukturnya
Umami vs Google Analytics vs Matomo vs Plausible
Sebelum install, penting buat tau posisi Umami dibanding alternatif lain. Ini perbandingan singkatnya biar kamu bisa milih yang paling cocok:
| Fitur | Umami | Google Analytics | Matomo | Plausible |
|---|---|---|---|---|
| Harga | Gratis (self-hosted) | Gratis | Gratis (self-hosted) / Berbayar (cloud) | Berbayar ($9/bln) / Self-hosted gratis |
| Cookie | Tidak pakai | Pakai | Opsional | Tidak pakai |
| Hosting | Self-hosted / Cloud | Google Cloud | Self-hosted / Cloud | Cloud / Self-hosted |
| Resource VPS | Ringan (~256MB RAM) | N/A | Berat (~1-2GB RAM) | Sedang (~512MB RAM) |
| Dashboard | Simpel, 1 halaman | Kompleks, banyak menu | Lengkap, mirip GA | Simpel, 1 halaman |
| GDPR Compliant | Ya (default) | Perlu konfigurasi | Ya (dengan setup) | Ya (default) |
| Ukuran Script | ~2KB | ~45KB | ~22KB | ~1KB |
| Database | PostgreSQL / MySQL | N/A | MySQL / MariaDB | PostgreSQL / ClickHouse |
| Open Source | Ya (MIT) | Tidak | Ya (GPL) | Ya (AGPL) |
Kenapa Umami yang dipilih di artikel ini? Karena dia paling ringan buat VPS kecil yang udah kepake buat WordPress dan Docker app lain. Matomo fiturnya lengkap tapi butuh resource gede. Plausible bagus tapi versi cloud-nya berbayar. Google Analytics gratis tapi data kamu di tangan Google. Umami ngasih sweet spot antara fitur yang cukup, resource yang irit, dan privasi yang terjaga.
Yang Perlu Disiapkan Sebelum Mulai
Sebelum mulai install Umami, pastiin semua prasyarat ini udah terpenuhi. Gak perlu banyak, tapi kalau ada yang kurang nanti bakal mentok di tengah jalan:
- VPS dengan minimal 1GB RAM – Umami sendiri cuma butuh ~256MB, tapi PostgreSQL juga butuh ruang. Kalau VPS kamu udah jalanin WordPress + Docker lain, idealnya sisa RAM minimal 512MB
- Docker dan Docker Compose terinstall – Kalau belum, ikutin dulu panduan cara install Docker di VPS
- Domain atau subdomain – Misalnya
analytics.domainmu.comyang udah di-pointing ke IP VPS kamu. Ini buat akses dashboard Umami lewat HTTPS - Reverse proxy aktif – Bisa pakai Traefik atau Cloudflare Tunnel buat handle HTTPS dan routing
- Akses SSH ke VPS – Semua perintah di artikel ini dijalanin lewat terminal SSH
- Website WordPress yang udah jalan – Tempat kamu bakal naruh script tracking Umami nantinya
Cara cek Docker udah terinstall:
docker --version
docker compose version
Kalau dua perintah di atas ngasih output versi (misalnya Docker version 24.x dan Docker Compose version v2.x), berarti kamu udah siap lanjut.
Langkah Instalasi Umami di VPS

Step 1: Bikin Folder Project Umami
Pertama, bikin folder khusus buat Umami. Ini penting biar file konfigurasi gak campur aduk sama project Docker lain di VPS kamu.
mkdir -p ~/docker/umami
cd ~/docker/umami
Kenapa pakai folder terpisah? Karena Docker Compose ngambil nama project dari nama folder. Kalau semua service ditaruh di satu folder, nanti nama container-nya bisa bentrok dan bikin bingung pas maintenance.
Step 2: Generate String Acak untuk APP_SECRET
Umami butuh APP_SECRET sebagai salt untuk enkripsi session. Jangan pakai string yang gampang ditebak – generate yang random:
openssl rand -base64 32
Output-nya bakal kayak gini (punya kamu pasti beda):
xK7mN2pQ9vR4tY8wB3jF6hL0sD5gA1cE7iU2oP4nM8=
Simpen output ini – bakal dipake di file docker-compose.yml nanti. Jangan share ke siapa-siapa karena ini kunci keamanan session dashboard kamu.
Step 3: Generate Password Database PostgreSQL
Sama kayak APP_SECRET, password database juga harus random dan kuat:
openssl rand -base64 24
Simpen juga output ini. Nanti dipake di dua tempat: environment variable PostgreSQL dan connection string Umami.
Step 4: Bikin File docker-compose.yml
Sekarang bikin file konfigurasi utama. Buka editor:
nano docker-compose.yml
Isi dengan konfigurasi berikut:
services:
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://umami:PASSWORD_DB_KAMU@db:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: STRING_ACAK_DARI_STEP_2
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: umami
POSTGRES_USER: umami
POSTGRES_PASSWORD: PASSWORD_DB_KAMU
volumes:
- umami_db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U umami"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
umami_db:
Sekarang ganti placeholder-nya:
PASSWORD_DB_KAMU– Ganti dengan output dari Step 3 (harus sama diDATABASE_URLdanPOSTGRES_PASSWORD)STRING_ACAK_DARI_STEP_2– Ganti dengan output dari Step 2
Penjelasan tiap bagian penting:
image: ghcr.io/umami-software/umami:postgresql-latest– Image resmi Umami yang udah dikonfigurasi buat PostgreSQL. Ada juga versi MySQL, tapi PostgreSQL lebih direkomendasikan karena performa query analytics-nya lebih bagusports: "3000:3000"– Umami jalan di port 3000. Kalau port ini udah kepake service lain, ganti angka pertama (misalnya"3001:3000")DATABASE_URL– Connection string ke PostgreSQL. Format:postgresql://USER:PASSWORD@HOST:PORT/DATABASE. Host-nyadbkarena itu nama service PostgreSQL di compose file yang samaAPP_SECRET– Salt untuk enkripsi session login. Tanpa ini, session gak amandepends_on: condition: service_healthy– Ini penting banget. Umami gak bakal start sebelum PostgreSQL beneran siap nerima koneksi. Tanpa ini, Umami bisa crash karena nyoba konek ke database yang belum readypostgres:15-alpine– Image PostgreSQL versi 15 yang ringan (Alpine Linux). Cukup stabil dan hemat resourcevolumes: umami_db– Named volume buat nyimpen data PostgreSQL. Ini yang bikin data gak ilang walau container di-recreatehealthcheck– PostgreSQL nge-check dirinya sendiri tiap 5 detik pakaipg_isready. Kalau gagal 5 kali berturut-turut, Docker anggap container-nya unhealthy
Step 5: Jalankan Docker Compose
Saatnya naikin semua container:
docker compose up -d
Flag -d artinya detached mode – container jalan di background. Pertama kali jalanin bakal agak lama karena Docker perlu download image Umami (~150MB) dan PostgreSQL (~80MB).
Expected output:
[+] Running 3/3
✔ Network umami_default Created
✔ Container umami-db-1 Healthy
✔ Container umami-umami-1 Started
Step 6: Cek Log untuk Memastikan Umami Jalan
Jangan langsung buka browser dulu. Cek dulu log-nya buat mastiin gak ada error:
docker compose logs -f umami
Expected output kalau sukses:
umami-umami-1 | ▲ Next.js 14.x.x
umami-umami-1 | - Local: http://localhost:3000
umami-umami-1 | ✓ Ready in 3.2s
Kalau muncul tulisan Ready, berarti Umami udah jalan dan siap diakses. Tekan Ctrl+C buat keluar dari log viewer.
Kalau muncul error? Jangan panik. Cek bagian Troubleshooting di bawah – kebanyakan masalah awal itu soal database belum ready atau typo di connection string.
Step 7: Cek Status Container
Verifikasi semua container jalan normal:
docker compose ps
Expected output:
NAME IMAGE STATUS
umami-db-1 postgres:15-alpine Up (healthy)
umami-umami-1 ghcr.io/umami-software/umami:postgresql-latest Up
Yang penting: status PostgreSQL harus Up (healthy), bukan cuma Up. Kalau masih Up (health: starting), tunggu beberapa detik lagi.
Konfigurasi dan Setup Awal Umami
Step 8: Login Pertama dan Ganti Password Default
Buka browser dan akses http://IP_VPS_KAMU:3000 (atau lewat domain kalau udah setup reverse proxy). Kamu bakal liat halaman login Umami.
Login pakai kredensial default:
- Username:
admin - Password:
umami
⚠️ PENTING: Kredensial ini sama buat semua orang yang install Umami. Langsung ganti password sekarang juga sebelum ngapa-ngapain lagi:
- Klik ikon profil di pojok kanan atas
- Pilih Profile
- Klik Change password
- Masukin password lama (
umami) dan password baru yang kuat - Klik Save
Step 9: Tambahkan Website ke Dashboard Umami
Setelah password diganti, sekarang daftarin website WordPress kamu:
- Klik menu Settings di sidebar kiri
- Pilih tab Websites
- Klik tombol Add website
- Isi Name dengan nama blog kamu (misalnya “Blog Jundi”)
- Isi Domain dengan domain blog (misalnya
jundi.hm) – tanpahttps:// - Klik Save
Setelah disave, Umami bakal generate Tracking Code yang unik buat website itu. Klik tombol Edit di website yang baru ditambah, lalu copy script tracking-nya. Bentuknya kayak gini:
<script defer src="https://analytics.domainmu.com/script.js" data-website-id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"></script>
Step 10: Pasang Script Tracking di WordPress
Ada beberapa cara buat masukin script tracking Umami ke WordPress. Pilih yang paling cocok sama setup kamu:
Cara 1: Lewat Plugin WPCode (Recommended)
- Install dan aktifkan plugin WPCode – Insert Headers and Footers dari dashboard WordPress
- Buka Code Snippets → Header & Footer
- Paste script tracking Umami di bagian Header
- Klik Save Changes
Cara 2: Lewat Theme Settings (JNews/GeneratePress)
Kalau theme kamu punya opsi custom header scripts (kayak JNews atau GeneratePress), tinggal paste di situ tanpa perlu plugin tambahan.
Cara 3: Manual lewat functions.php
function add_umami_tracking() {
echo '<script defer src="https://analytics.domainmu.com/script.js" data-website-id="ID_KAMU"></script>';
}
add_action('wp_head', 'add_umami_tracking');
⚠️ Cara manual lewat functions.php bakal hilang kalau theme di-update. Lebih aman pakai child theme atau plugin WPCode.
Step 11: Setup Reverse Proxy untuk HTTPS
Dashboard Umami sebaiknya gak diakses lewat HTTP biasa (port 3000 langsung). Kenapa? Karena password login kamu dikirim tanpa enkripsi – siapa aja yang nyadap jaringan bisa baca. Selain itu, script tracking juga perlu HTTPS biar gak diblok browser modern.
Ada dua opsi yang udah dibahas di blog ini:
- Traefik Reverse Proxy – Cocok kalau kamu mau manage SSL certificate sendiri dan punya banyak service Docker yang perlu di-expose
- Cloudflare Tunnel – Cocok kalau kamu gak mau buka port sama sekali ke publik. Semua trafik lewat jaringan Cloudflare
Kalau pakai Cloudflare Tunnel, kamu bahkan bisa hapus bagian ports di docker-compose.yml karena Umami gak perlu expose port ke luar. Lebih aman lagi kalau dikombinasiin sama DockFlare buat otomatis manage tunnel-nya.
Testing dan Verifikasi
Step 12: Verifikasi Script Tracking Terpasang
Buka blog WordPress kamu di browser, lalu klik kanan → View Page Source (atau tekan Ctrl+U). Cari kata “umami” atau “script.js” di source code. Kalau ketemu, berarti script-nya udah terpasang.
Bisa juga cek lewat terminal:
curl -s https://blogkamu.com | grep -i "umami"
Expected output:
<script defer src="https://analytics.domainmu.com/script.js" data-website-id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"></script>
Step 13: Cek Data Masuk di Dashboard
Setelah script terpasang:
- Buka blog kamu di tab baru (atau minta temen buka)
- Klik beberapa halaman biar ada data pageview
- Buka dashboard Umami
- Pilih website yang udah didaftarin
- Cek bagian Realtime – harusnya kunjungan kamu udah muncul dalam hitungan detik
Kalau data belum muncul setelah 1-2 menit, cek hal-hal berikut:
- Pastiin domain di setting Umami cocok sama domain blog kamu
- Cek browser console (
F12→ tab Console) – ada error loading script gak? - Kalau pakai plugin caching di WordPress (WP Super Cache, W3 Total Cache, dll), purge cache dulu biar halaman yang baru dipasangin script ke-serve ke pengunjung
- Cek apakah adblocker di browser kamu nge-block script Umami
Step 14: Benchmark Resource Usage
Cek seberapa banyak resource yang dipake Umami di VPS kamu:
docker stats --no-stream --format "table {{.Name}} {{.CPUPerc}} {{.MemUsage}}" umami-umami-1 umami-db-1
Expected output (kurang lebih):
NAME CPU % MEM USAGE / LIMIT
umami-umami-1 0.15% 180MiB / 1.94GiB
umami-db-1 0.05% 45MiB / 1.94GiB
Total sekitar 200-250MB RAM buat Umami + PostgreSQL. Cukup irit buat VPS yang udah jalanin banyak service. Kalau kamu juga pakai Beszel atau Netdata buat monitoring, bisa pantau resource usage Umami dari situ juga.
Troubleshooting: Masalah yang Sering Muncul
Berikut masalah-masalah yang paling sering ketemu pas setup Umami, lengkap sama cara benerinnya:
Container Umami Restart Loop
Gejala: Container umami terus restart, log nunjukin error koneksi database.
Penyebab: Umami nyoba konek ke PostgreSQL sebelum database-nya siap.
Solusi: Pastiin bagian depends_on pakai condition: service_healthy, bukan cuma list nama service. Ini yang bikin Docker nunggu sampai PostgreSQL beneran ready sebelum start Umami.
# ❌ Salah - cuma nunggu container start, bukan ready
depends_on:
- db
# ✅ Benar - nunggu sampai healthcheck pass
depends_on:
db:
condition: service_healthy
Error Format DATABASE_URL
Gejala: Log nunjukin error parsing connection string atau “invalid connection string”.
Penyebab: Format URL gak cocok sama tipe database yang dipake.
Solusi: Kalau pakai image postgresql-latest, URL harus diawali postgresql://. Kalau pakai image mysql-latest, URL harus diawali mysql://. Jangan ketuker.
# Untuk PostgreSQL
DATABASE_URL: postgresql://umami:password@db:5432/umami
# Untuk MySQL
DATABASE_URL: mysql://umami:password@db:3306/umami
Password Database Gak Cocok
Gejala: Error “password authentication failed for user umami”.
Penyebab: Password di DATABASE_URL beda sama POSTGRES_PASSWORD.
Solusi: Pastiin password di dua tempat ini identik. Kalau udah terlanjur salah dan container database udah pernah jalan, kamu perlu hapus volume dulu biar database di-create ulang:
docker compose down -v
docker compose up -d
⚠️ Flag -v bakal hapus semua data di volume. Cuma lakukan ini kalau Umami baru pertama kali di-setup dan belum ada data penting.
Script Tracking Diblok Adblocker
Gejala: Script terpasang di source code tapi data gak masuk ke dashboard.
Penyebab: Filter list kayak EasyPrivacy mulai ngedaftarin domain analitik self-hosted, bukan cuma Google Analytics.
Solusi: Pakai subdomain yang gak mengandung kata “analytics”, “stats”, “tracking”, atau “umami”. Misalnya data.domainmu.com atau pixel.domainmu.com. Umami juga punya fitur rename script path di environment variable:
environment:
TRACKER_SCRIPT_NAME: custom-script-name
Warning APP_SECRET Kosong
Gejala: Muncul warning di log soal APP_SECRET kosong atau default.
Penyebab: Environment variable APP_SECRET gak diisi atau masih pakai placeholder.
Solusi: Generate string acak pakai openssl rand -base64 32 dan masukin ke environment variable. Umami tetep jalan tanpa ini, tapi session login jadi kurang aman karena salt-nya predictable.
Port 3000 Udah Kepake Service Lain
Gejala: Error “bind: address already in use” pas docker compose up.
Penyebab: Ada service lain (misalnya Grafana, n8n, atau app Node.js) yang udah pake port 3000.
Solusi: Ganti port mapping di docker-compose.yml. Angka pertama itu port di host, angka kedua itu port di dalam container:
# Ganti 3000 pertama ke port yang kosong
ports:
- "3001:3000"
Cek port yang lagi kepake:
ss -tlnp | grep 3000
Data Caching WordPress Bikin Script Gak Ke-load
Gejala: Script udah ditambah tapi gak muncul di source code halaman.
Penyebab: Plugin caching WordPress masih nge-serve versi halaman yang lama (sebelum script ditambah).
Solusi: Purge semua cache – baik di plugin caching (WP Super Cache, W3 Total Cache, LiteSpeed Cache) maupun di Cloudflare kalau kamu pakai. Setelah purge, hard refresh browser (Ctrl+Shift+R) dan cek lagi source code-nya.
Soal Database: Kenapa PostgreSQL-nya Dipisah dari MySQL WordPress
Kalau VPS kamu udah jalanin WordPress yang pakai MySQL, mungkin kepikiran: “Kenapa gak gabungin aja ke satu database biar hemat resource?” Ini pertanyaan yang valid, tapi jawabannya: jangan.
Alasannya bukan cuma soal beda engine (PostgreSQL vs MySQL). Lebih ke soal isolasi risiko:
- Kalau satu database lag, semua app ikut kena – Query analytics yang berat dari Umami bisa bikin WordPress jadi lemot, atau sebaliknya
- Backup jadi lebih bersih – Tinggal snapshot volume PostgreSQL-nya aja, gak perlu nge-dump seluruh database WordPress yang jauh lebih gede
- Upgrade independen – Mau upgrade PostgreSQL dari 15 ke 16? Tinggal ganti image, gak ngaruh ke MySQL WordPress
- Port gak bentrok – PostgreSQL di 5432, MySQL di 3306. Jalan bareng tanpa masalah
Dari pengalaman ngurus server yang jalanin WordPress plus beberapa Docker app sekaligus, pemisahan database kayak gini bikin hidup jauh lebih gampang pas troubleshooting. Kalau Umami bermasalah, tinggal restart container-nya tanpa takut ngaruh ke WordPress.
Kesimpulan
Sekarang kamu punya Umami yang jalan di VPS sendiri – analitik web yang ringan, privacy-friendly, dan datanya 100% milik kamu. Gak ada data pengunjung yang numpang lewat server pihak ketiga.
Rangkuman yang udah kamu lakuin:
- Deploy Umami + PostgreSQL pakai Docker Compose
- Konfigurasi keamanan (ganti password default, APP_SECRET, HTTPS)
- Pasang script tracking di WordPress
- Verifikasi data masuk ke dashboard
Buat maintenance ke depan:
- Update image Umami secara berkala – bisa pakai Watchtower buat auto-update
- Backup volume PostgreSQL minimal seminggu sekali
- Pantau resource usage lewat Beszel atau Netdata
- Cek changelog Umami tiap ada major release buat tau fitur baru atau breaking changes
Gak perlu buru-buru cabut Google Analytics yang lama. Jalanin dua-duanya bareng selama 2-4 minggu buat bandingin angkanya. Kalau udah yakin data Umami akurat dan cukup buat kebutuhan kamu, baru deh lepas Google Analytics dan nikmatin dashboard yang bersih tanpa cookie banner. 🎯

























