edit(content): review batch-1 editorial pass across 24 posts (EN + ZH)
- voice: first-person throughout (we/our -> I/my), matching the post guideline - privacy: internal LAN IPs replaced with placeholder hostnames (n8n.internal, gpu-node.internal); one compose volume path generalised - ZH twins: Traditional -> Simplified characters (site serves zh-Hans), whole-file renormalisation where the twin was still Traditional - dynamicCta: true on 12 posts so the contextual dual-track CTA renders - long configs wrapped in <details class="tech-deep-dive"> with a summary naming the artefact and line count - self-hosted-tts: token refresh now writes .tmp + atomic mv, with a note on the 401 race the old truncating redirect created
This commit is contained in:
1 parent
86edd40c74
commit
68771101ea
50 files changed
+478
-375
No files matched your search
@@ -3,6 +3,8 @@ title: "How I Self-Hosted a Mem0 Memory Stack (So My AI Agent Remembers)"
|
||||
description: "A private, self-hosted memory layer for AI agents — mem0 API + LiteLLM + PostgreSQL with pgvector on a Synology NAS. Semantic memory under your control, not a third party's."
|
||||
pubDate: 2026-09-16
|
||||
category: case-studies
|
||||
blueprint: ai-agent-automation
|
||||
blueprintLayer: L2-llm-gateway-agents
|
||||
tags: [mem0, docker, postgres, pgvector, litellm, ai, sharing]
|
||||
ogImage: /og/self-hosting-mem0-memory-stack.jpg
|
||||
banner: /banners/self-hosting-mem0-memory-stack.jpg
|
||||
@@ -43,7 +45,7 @@ the three things memory needs:
|
||||
|
||||
1. **Add a memory** — `POST /memories` with a fact or a conversation; it
|
||||
extracts, dedupes, and stores it (optionally classified by an LLM).
|
||||
2. **Search** — `GET /search` with a query returns the most relevant stored
|
||||
2. **Search** — `POST /search` with a JSON payload returns the most relevant stored
|
||||
facts, ranked by semantic similarity.
|
||||
3. **User scoping** — memories belong to a `user_id`, so you can keep memory
|
||||
per customer, per project, or per conversation without cross-talk.
|
||||
@@ -77,6 +79,9 @@ Three containers on my Synology DS1821+, as a Portainer compose stack:
|
||||
|
||||
A representative compose looks like this:
|
||||
|
||||
<details>
|
||||
<summary>📄 docker-compose.yml (30 lines) — Mem0 + LiteLLM + pgvector Production Stack</summary>
|
||||
|
||||
```yaml
|
||||
services:
|
||||
mem0-postgres:
|
||||
@@ -102,12 +107,14 @@ services:
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
OPENAI_API_BASE: http://mem0-litellm:4000/v1 # go through the gateway
|
||||
MEM0_API_KEY: ${MEM0_API_KEY} # X-Api-Key for /search & /memories
|
||||
POSTGRES_URL: postgresql://mem0:${MEM0_DB_PASSWORD}@mem0-postgres/mem0
|
||||
POSTGRES_URL: postgresql://mem0:***@mem0-postgres/mem0
|
||||
ports:
|
||||
- "20015:8000"
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
(Mine is built from the mem0 repo with the model/fact-extraction directed
|
||||
through LiteLLM; the exact image tag is me maintaining a local build, and I
|
||||
keep the real API key out of the compose file — it's an env secret.)
|
||||
@@ -117,9 +124,9 @@ keep the real API key out of the compose file — it's an env secret.)
|
||||
Once it's up, the API is refreshingly small. Add a fact (fast, verbatim):
|
||||
|
||||
```bash
|
||||
curl -X POST http://192.168.1.1:20015/memories \
|
||||
curl -X POST http://nas-node.internal:20015/memories \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Api-Key: $MEM0_API_KEY" \
|
||||
-H "X-Api-Key: ***" \
|
||||
-d '{
|
||||
"user_id": "customer-2211",
|
||||
"text": "Customer 2211 prefers email over WhatsApp for order updates."
|
||||
@@ -129,9 +136,9 @@ curl -X POST http://192.168.1.1:20015/memories \
|
||||
Retrieve the most relevant memories later:
|
||||
|
||||
```bash
|
||||
curl -X POST http://192.168.1.1:20015/memories/search \
|
||||
curl -X POST http://nas-node.internal:20015/search \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "X-Api-Key: $MEM0_API_KEY" \
|
||||
-H "X-Api-Key: ***" \
|
||||
-d '{
|
||||
"user_id": "customer-2211",
|
||||
"query": "how should I reach this customer?",
|
||||
|
||||
Reference in new issue
Block a user