Cara Install Umami di VPS: Analitik Website Tanpa Cookie

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.

diagram arsitektur umami

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:

FiturUmamiGoogle AnalyticsMatomoPlausible
HargaGratis (self-hosted)GratisGratis (self-hosted) / Berbayar (cloud)Berbayar ($9/bln) / Self-hosted gratis
CookieTidak pakaiPakaiOpsionalTidak pakai
HostingSelf-hosted / CloudGoogle CloudSelf-hosted / CloudCloud / Self-hosted
Resource VPSRingan (~256MB RAM)N/ABerat (~1-2GB RAM)Sedang (~512MB RAM)
DashboardSimpel, 1 halamanKompleks, banyak menuLengkap, mirip GASimpel, 1 halaman
GDPR CompliantYa (default)Perlu konfigurasiYa (dengan setup)Ya (default)
Ukuran Script~2KB~45KB~22KB~1KB
DatabasePostgreSQL / MySQLN/AMySQL / MariaDBPostgreSQL / ClickHouse
Open SourceYa (MIT)TidakYa (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.com yang 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 by step instalasi

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 di DATABASE_URL dan POSTGRES_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 bagus
  • ports: "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-nya db karena itu nama service PostgreSQL di compose file yang sama
  • APP_SECRET – Salt untuk enkripsi session login. Tanpa ini, session gak aman
  • depends_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 ready
  • postgres:15-alpine – Image PostgreSQL versi 15 yang ringan (Alpine Linux). Cukup stabil dan hemat resource
  • volumes: umami_db – Named volume buat nyimpen data PostgreSQL. Ini yang bikin data gak ilang walau container di-recreate
  • healthcheck – PostgreSQL nge-check dirinya sendiri tiap 5 detik pakai pg_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:

  1. Klik ikon profil di pojok kanan atas
  2. Pilih Profile
  3. Klik Change password
  4. Masukin password lama (umami) dan password baru yang kuat
  5. Klik Save

Step 9: Tambahkan Website ke Dashboard Umami

Setelah password diganti, sekarang daftarin website WordPress kamu:

  1. Klik menu Settings di sidebar kiri
  2. Pilih tab Websites
  3. Klik tombol Add website
  4. Isi Name dengan nama blog kamu (misalnya “Blog Jundi”)
  5. Isi Domain dengan domain blog (misalnya jundi.hm) – tanpa https://
  6. 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)

  1. Install dan aktifkan plugin WPCode – Insert Headers and Footers dari dashboard WordPress
  2. Buka Code Snippets → Header & Footer
  3. Paste script tracking Umami di bagian Header
  4. 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:

  1. Buka blog kamu di tab baru (atau minta temen buka)
  2. Klik beberapa halaman biar ada data pageview
  3. Buka dashboard Umami
  4. Pilih website yang udah didaftarin
  5. 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. 🎯

Jundi Husni Mubaraq

Jundi Husni Mubaraq

Saya seorang software engineer yang sejak awal 2026 megang penuh (sendirian) tanggung jawab infrastruktur server di tempat saya kerja: deploy dan maintain server Linux Ubuntu on-premises, bangun keamanan berlapis pakai CrowdSec dan Cloudflare, kelola job scheduling dan monitoring pakai Cronicle, deploy aplikasi containerized pakai Docker, sampai ngurusin mail server korporat dari nol. Sebelumnya saya 3+ tahun jadi Software Engineer/Fullstack Developer di beberapa perusahaan, termasuk proyek skala internasional (EUDR compliance system buat Lindt & Sprungli) dan sistem rumah sakit (SIMRS, rekam medis elektronik, integrasi BPJS Kesehatan) di RS PKU Muhammadiyah Surakarta. jundi.hm ini tempat saya dokumentasiin apa yang beneran saya kerjain dan pelajarin di lapangan, bukan sekadar riset teori, S.Kom dari Universitas Duta Bangsa Surakarta jadi bekal awal, tapi yang nulis di sini adalah pengalaman langsung ngelola server production sehari-hari. Selengkapnya: https://iam.jundi.hm

Lihat Juga Nih

Selanjutnya Nih

Kasih Komentar

Email kamu gak bakal ditampilin ke publik. Kalau ada tanda ini artinya wajib diisi ya *

Rekomendasi.

Lagi Viral.