Self-Host mem0 di VPS: 9 Jebakan yang Bikin Dashboard Blank
mem0 itu lapisan memori untuk AI agent — tempat nyimpen fakta, preferensi, dan konteks obrolan biar agent ga lupa siapa kamu tiap sesi baru. Versi cloud-nya gampang: daftar, copy API key, beres. Tapi begitu kamu pilih self-host, semua kemudahan itu hilang dan gantinya 9 jebakan yang ga ada di quickstart resmi. Kami habiskan satu hari penuh pasang mem0 di VPS sendiri sampai dashboard-nya benar-benar bisa login.
Kenapa repot-repot self-host?
Kalau kamu pakai mem0 cloud, memori agent kamu — yang isinya bisa jadi kebiasaan kerja, data klien, sampai potongan percakapan sensitif — disimpan di server orang lain, dengan harga yang bisa berubah tiap kuartal. Self-host memindahkan seluruh lapisan itu ke VPS kamu sendiri: Postgres jalan di mesinmu, embedding dihitung pakai key kamu, dan tidak ada satu pun request keluar ke mem0.ai.
Triknya: server self-host memakai provider openai yang sudah dibundel mem0, tapi openai_base_url diarahkan ke gateway LLM kita sendiri. Jadi kita tidak perlu patch library mem0 supaya bisa pakai provider baru — cukup arahkan base URL-nya. Hemat biaya besar, dan tetap dapat API + dashboard yang sama.
Kalau kamu masih ragu mau pakai mem0 atau engine lain, dua perbandingan yang pernah kami tulis bisa jadi bahan: mem0 vs Hindsight untuk self-host dan mem0 MCP vs Hindsight.
Arsitektur: 3 container, satu database
Bundle self-host mem0 sebenarnya sederhana. Docker Compose di folder server/ menjalankan tiga hal:
| Container | Port | Fungsi |
|---|---|---|
mem0-api |
8888 | REST API (FastAPI + uvicorn) |
mem0-dashboard |
3000 | Dashboard (Next.js) |
postgres |
5432 | Postgres + pgvector (vector store) |
Dua port wajib kamu ingat: 8888 untuk API, 3000 untuk dashboard. Kalau pakai reverse proxy, proxy dua-duanya — bukan cuma dashboard-nya.
9 jebakan yang bikin dashboard blank
Semua poin ini kami alami sendiri, jadi anggap ini daftar periksa sebelum kamu mulai:
- Provider LLM hardcoded. Set
GOOGLE_API_KEYsaja tidak cukup — default-nya tetap OpenAI. Ganti provider di config, bukan di env. - Package tidak dibundel. Beberapa provider butuh paket tambahan (mis.
google-genai) direquirements.txt. Kalau tidak, container crash saat start. - Nama model sudah usang. Model embedding dan LLM berganti nama sepanjang tahun — cek dulu model apa yang masih hidup sebelum menulis config.
- Dimensi embedding tidak cocok (paling jahat). pgvector default 1536 dimensi, sementara model embedding tertentu mengeluarkan 768. Gejalanya menipu: API membalas
event: ADDseolah sukses, tapiSELECT count(*)tetap 0. Setembedding_model_dims, lalu drop tabel dan biarkan dibuat ulang. openai_base_urlikut ke embedder. Ini bikinprovider_bad_requestkarena endpoint chat dipakai untuk embedding. LLM dan embedder harus dipisah konfigurasinya.DASHBOARD_URLdi-bake, bukan dibaca runtime. Di dashboard Next.js, variabelNEXT_PUBLIC_*disuntik saat build. Restart container tidak mengubah apa pun — kamu wajib rebuild, kalau tidak frontend akan terus memanggilhttp://localhost:8888.command:di docker-compose menimpa CMD Dockerfile. Ini sumber bug halus:--reloadmembuat dua proses jalan sekaligus, dan rate limiter jadi tidak berguna.- Rate limiting butuh middleware. Pasang slowapi dengan
app.state.limiter+SlowAPIMiddleware; tanpa itu login dan registrasi bisa dibruteforce tanpa hambatan. - Dashboard butuh HTTPS + domain. Simpan sesi di HTTP dengan IP mentah sering gagal. Begitu diberi domain + TLS, login-nya langsung normal.
Jebakan nomor 6 itu masalah komunitas, bukan salahmu
Kalau kamu cari “mem0 self-hosted login network error”, kamu akan ketemu issue lama di repo mem0 yang masih dibalas sampai Agustus 2026: dashboard memanggil localhost:8888, dan jawaban di thread itu menyarankan set API_BASE_URL=http://IP-SERVER:8888. Saran itu belum cukup. Karena variabelnya NEXT_PUBLIC_*, menambahkannya ke .env tanpa rebuild hanya akan mengubah nama variabel, bukan isi bundle JavaScript yang sudah dikirim ke browser. Kalau kamu mentok di titik ini, langsung ke rebuild — jangan berputar-putar ganti port seperti kami.
Verifikasi: jangan percaya respons API
Pelajarannya paling mahal: respons API bisa berbohong. Kasus dimensi embedding tadi membuat endpoint /memories membalas sukses sementara tabel memorinya kosong.
Selalu verifikasi dua sisi:
# sisi API
curl -X POST https://mem0-api.contoh.com/search \
-H "Content-Type: application/json" \
-d '{"query":"preferensi saya","user_id":"tester"}'
# sisi database — ini yang menentukan
SELECT count(*) FROM memories;
Kalau angka di database nol, masalahnya bukan di client kamu.
Kesimpulan
Self-host mem0 bukan proyek sekali klik, tapi juga bukan hal yang mustahil. Panduan resminya ada di docs.mem0.ai/open-source/setup, dan kalau kamu mentok di masalah dashboard bisa dilihat di issue #4993 — di sana kelihatan bahwa masalah localhost:8888 masih hidup sampai sekarang. Sembilan poin di atas semuanya soal satu tema: config yang tampak benar tapi tidak terbaca di tempat yang kamu kira. Setelah semua itu beres, kamu punya lapisan memori agent yang jalan sepenuhnya di infrastruktur sendiri — plus dashboard yang bisa kamu lock ke IP tertentu saja supaya tidak ada orang lain yang bisa lihat isi memori agent kamu.
Kalau kamu juga menjalankan mem0 atau memory engine lain di VPS sendiri, bagi pengalamanmu di kolom komentar — terutama kalau kamu nemu jebakan kesepuluh yang belum kami tulis di sini.
— Chokdi 🐷 · Content Studio · 2026