Jinsi ya ku-self-host mem0 kwenye VPS yako
Jifunze kuendesha mem0 kwenye VPS kwa kutumia Docker Compose. Pata mwongozo wa usanidi wa TLS, ufungaji wa Ollama, na mahitaji halisi ya RAM ili kuepuka makosa ya kumbukumbu.
Gharama halisi ya RAM kwa ajili ya ku-self-host mem0 kwenye VPS
Ku-self-host mem0 kunamaanisha kuendesha container tatu: seva ya kumbukumbu ya FastAPI, Postgres yenye extension ya pgvector, na dashboard ya Next.js. mem0 ni safu ya kumbukumbu kwa ajili ya mawakala (agents). Unatuma mazungumzo kwake, modeli ya lugha huchota ukweli wa kudumu kutoka kwenye mazungumzo hayo, na ukweli huo huhifadhiwa kama vekta ili swali la baadaye liweze kuchota yale yanayohusika.
Tenga takriban 1 GB ya kumbukumbu ya resident kwa ajili ya container hizo tatu, na 3 hadi 4 GB ya diski pindi images zitakapojengwa. VPS ya 2 GB huendesha haya kwa urahisi wakati modeli ya lugha inapokuwa mahali pengine. Modeli inapoendeshwa kwenye mashine hiyo hiyo kupitia Ollama, modeli hiyo hutawala kila kitu kingine: modeli ya 8B iliyopunguzwa (quantised) hadi bits 4 huhitaji takriban 6 GB peke yake, kwa hivyo ujenzi wa ndani kabisa huanzia 8 GB.
Usichukulie takwimu hizo kutoka kwenye chapisho la blogu, ikiwemo hili. Pima stack uliyojenga wewe mwenyewe.
docker compose ps
docker stats --no-stream
docker system df -vdocker stats huchapisha kumbukumbu ya resident kwa kila container. docker system df -v huchapisha diski inayoshikiliwa na kila image na kila volume.
Hali ya utulivu (steady state) si kilele cha matumizi. docker compose up -d --build huandaa (compile) dashboard ya Next.js, na ujenzi huo wa Node ndio wakati wenye njaa zaidi katika usakinishaji mzima. Kwenye VPS ya 1 GB, kernel out-of-memory killer huizuia na ujenzi huishia na exit code 137. Thibitisha sababu kabla ya kuanza kutafuta hitilafu ya Docker:
dmesg -T | grep -i "killed process"Ikiwa seva inaonekana kama mashine nyingi mno kwa unachohitaji, chaguzi ndogo ni halisi. hifadhi ya kumbukumbu ya wakala wa ndani bila seva yoyote na kumbukumbu inayokaa ndani ya Claude Code yenyewe zote huruka database. Rudi hapa wakati mawakala kadhaa, au mashine kadhaa, zinahitaji kusoma kumbukumbu zile zile.
Je, ninahitaji Neo4j kwa ajili ya mem0 graph memory?
Hapana. Ikiwa mwongozo unakuambia uongeze container ya Neo4j, mwongozo huo umepitwa na wakati.
Graph memory katika mem0 ilimaanisha hifadhidata ya nje ya graph, iliyosanidiwa chini ya ufunguo wa graph_store huku enable_graph ikiwa imewekwa kuwa true. Algorithm mpya ya kumbukumbu, iliyotolewa mwezi Aprili 2026, iliondoa funguo zote mbili kutoka kwenye SDK ya open source. Uchimbaji wa entity sasa unafanyika ndani ya njia ya kawaida ya add, na entities huandikwa kwenye mkusanyiko wa pili wa pgvector uliopewa jina la mkusanyiko wako mkuu na kuongezewa _entities mwishoni. Hakuna migration ya kufanya. Uunganishaji wa entity uliojengewa ndani huanza kufanya kazi kwenye ombi la add linalofuata.
Kuondoa graph store huokoa container ya JVM, heap yake, na mamia kadhaa ya megabytes ya image. Kwenye VPS ya 2 GB, hiyo ndiyo tofauti kati ya programu kufanya kazi vizuri na kuanza kutumia swap.
Hivi ndivyo unavyopoteza, kwa ufafanuzi: Matokeo ya utafutaji yalikuwa na uwanja wa relations uliorodhesha mahusiano (edges) kati ya entities. Uwanja huo haupo tena. Mechi za entity sasa huongeza nafasi ya kumbukumbu katika alama ya pamoja, na hakuna muundo unaoweza kuupitia. Ikiwa programu yako ilikuwa ikipitia mahusiano hayo, mem0 haiyashikilii tena, na unapaswa kutumia hifadhidata yako ya graph nje ya mem0, inayolishwa na msimbo wako mwenyewe.
Faili la compose lililopo kwenye repo ni la maendeleo
server/docker-compose.yaml linatangaza name: mem0-dev, na lina maana hiyo. Lisome kabla ya kuliendesha, kwa sababu mambo matano ndani yake hayafai kwa seva.
- Linajenga kutoka
server/dev.Dockerfilena ku-mount checkout yako juu ya image kwa kutumia.:/app, kwa hivyo container inaendesha chochote kilichopo kwenye saraka hiyo badala ya kile ulichokijenga. - Amri yake ni
rm -rf /app/packages && pip install -q --force-reinstall --no-deps mem0ai && alembic upgrade head && uvicorn main:app --reload. Hiyo inasakinisha upyamem0aikutoka PyPI kila inapoanza, kwa hivyo toleo ambalo seva yako inaendesha linaweza kubadilika wakati wa restart ambayo hukudhani ni upgrade. - Hatua hiyo ya pip inamaanisha kuwa restart bila network ya nje itafeli kabla ya uvicorn kuanza. Seva yako ya kumbukumbu itakuwa chini kwa sababu PyPI haikufikika.
--reloadinaanza file watcher ya uvicorn. Ipo ili kuanzisha upya mchakato unapohariri msimbo, na inatumia kumbukumbu na mchakato wa pili bila kufanya kazi yoyote muhimu katika uzalishaji.Dockerfileya uzalishaji inabeba--reloadndani yaCMDyake pia, kwa hivyo una-override amri kwa njia yoyote ile.- Port zilizochapishwa ni
"8888:8000","8432:5432"na"3000:3000". Port iliyochapishwa bila anwani mbele yake inafungwa kwenye0.0.0.0, kwa hivyo Postgres inajibu mtandao wa umma kwenye 8432 mara tu stack inapoanza.
Hoja hiyo ya mwisho inastahili onyo lake yenyewe. Docker inachapisha port kwa kuandika sheria zake yenyewe mbele ya mnyororo unaosimamiwa na ufw, kwa hivyo ufw deny 8432 haifungi port ya container iliyochapishwa. Docker kuchapisha port moja kwa moja kupita ufw inaelezea sheria zinazohusika.
Faili ya compose kwa seva halisi
Fanya kazi ndani ya server/, weka init-db.sh mahali pake, na ubadilishe docker-compose.yaml na hii.
name: mem0
services:
mem0:
build:
context: .
dockerfile: Dockerfile
restart: unless-stopped
env_file: .env
ports:
- "127.0.0.1:8888:8000"
networks: [mem0_network]
volumes:
- mem0_history:/app/history
depends_on:
postgres:
condition: service_healthy
command: >
sh -c "alembic upgrade head &&
uvicorn main:app --host 0.0.0.0 --port 8000"
environment:
- PYTHONUNBUFFERED=1
- DASHBOARD_URL=https://mem0.example.com
- APP_DB_NAME=mem0_app
- AUTH_DISABLED=false
- MEM0_TELEMETRY=false
postgres:
image: pgvector/pgvector:pg17
restart: unless-stopped
shm_size: "128mb"
networks: [mem0_network]
environment:
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}
healthcheck:
test: ["CMD-SHELL", "pg_isready -q -U ${POSTGRES_USER:-postgres}"]
interval: 5s
timeout: 5s
retries: 5
volumes:
- postgres_db:/var/lib/postgresql/data
- ./init-db.sh:/docker-entrypoint-initdb.d/init-db.sh
mem0-dashboard:
build: ./dashboard
restart: unless-stopped
ports:
- "127.0.0.1:3000:3000"
networks: [mem0_network]
environment:
- NEXT_PUBLIC_API_URL=https://mem0.example.com
- API_INTERNAL_URL=http://mem0:8000
depends_on:
mem0:
condition: service_started
volumes:
postgres_db:
mem0_history:
networks:
mem0_network:
driver: bridgeMabadiliko matano ni muhimu hapa, na kila moja lina sababu yake.
Kila ingizo la ports huanza na 127.0.0.1, ili kernel ikubali miunganisho hiyo kutoka kwenye seva yenyewe pekee. Kila kitu kutoka nje hufika kupitia reverse proxy, ambayo ndiyo pekee inayoshikilia cheti.
Postgres haina block ya ports hata kidogo. Container ya mem0 huifikia kupitia mem0_network kwa kutumia jina la huduma, kwa hivyo kuchapisha 8432 hakukupi faida yoyote na kunagharimu port iliyo wazi. Tumia docker compose exec postgres psql -U postgres unapohitaji shell.
Historia huhama kutoka bind mount ya ./history kwenda kwenye named volume. Bind mount hufunga data kwenye njia moja na uid moja kwenye host hii, wakati named volume ni kitu ambacho Docker inaweza kukipiga snapshot na kukihamisha. Named volumes dhidi ya bind mounts inaelezea wakati ambapo kila moja inafaa.
Amri huondoa --reload na kuhifadhi alembic upgrade head. Hifadhi hatua hiyo ya uhamiaji. Bila hiyo, programu huwaka dhidi ya database isiyo na majedwali, na kila ombi hushindwa kwenye query ya kwanza.
NEXT_PUBLIC_API_URL ndiyo URL ambayo kivinjari chako huita, kwa hivyo lazima iwe anwani ya umma ya HTTPS na si http://mem0:8000. Next.js huweka thamani ya kila NEXT_PUBLIC_ wakati wa build, kwa hivyo kuibadilisha kunahitaji docker compose up -d --build mem0-dashboard. Restart ya kawaida huhifadhi thamani ya zamani iliyopikwa ndani ya JavaScript na dashboard huita host isiyo sahihi.
Siri huhifadhiwa kwenye .env, na .env haipaswi kufikiwa na mtandao
cd server
cp .env.example .env
openssl rand -hex 32 # paste into JWT_SECRET
openssl rand -hex 32 # paste into ADMIN_API_KEY
chmod 600 .envWeka POSTGRES_PASSWORD, JWT_SECRET na ADMIN_API_KEY. Acha AUTH_DISABLED=false kama ilivyo. Jina la flag hii linaeleza wazi kazi yake: ikiwa imewashwa, seva hutoa kumbukumbu zake zote kwa yeyote anayeweza kufikia port hiyo. Weka MEM0_TELEMETRY=false ikiwa hutaki tukio la onboarding litumwe kwenye mfumo wa juu (upstream).
ADMIN_API_KEY inalinganishwa na header ya X-API-Key kwa kutumia secrets.compare_digest, na zikilingana, mfumo huruka hatua zote za kutafuta kwenye database. Hii ni credential ya root kwa API nzima. Ichukulie kama ilivyo: usiihifadhi kwenye shell history, usiweke kwenye git, na usiiweke kwenye prompt yoyote. Kutunga faili za Compose env na mahali siri zinapovuja kutoka humo na kuepusha API keys kwenye muktadha wa agent zote zinahusika moja kwa moja, kwa sababu wanaopiga simu kwenye seva hii ni agents.
Thamani zinazopakiwa kutoka env_file hukaa kwenye mazingira ya container, na docker inspect huzichapisha zote. Mtu yeyote aliye kwenye kundi la docker anaweza kuzisoma, na mtu yeyote aliye kwenye kundi la docker ana mamlaka sawa na root kwenye host.
Weka TLS mbele ya API badala ya kufungua 8888
API inajibu kwenye 127.0.0.1:8888 na dashibodi kwenye 127.0.0.1:3000. nginx inafanya TLS (transport layer security) termination kwenye 443 na kusambaza maombi kwa zote mbili.
server {
listen 443 ssl;
server_name mem0.example.com;
ssl_certificate /etc/letsencrypt/live/mem0.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mem0.example.com/privkey.pem;
location ~ ^/(memories|search|configure|auth|api-keys|docs|openapi.json) {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 180s;
}
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}proxy_read_timeout ni muhimu zaidi kuliko inavyoonekana. Wito wa add huzuia mchakato wakati language model inasoma mazungumzo na kuchimba taarifa. Model ya 8B ya ndani kwenye CPU mara nyingi huchukua muda mrefu kuliko muda wa kawaida wa sekunde 60 wa nginx, na kisha mpigaji huona 504 Gateway Time-out wakati model bado inafanya kazi na kumbukumbu bado inaandikwa. Unajikuta na kumbukumbu ambayo uliambiwa imefeli.
Funga sehemu nyingine kwa kutumia sera ya default deny ya ufw, ukiacha 22 na 443 wazi. Toa cheti kwa kutumia certbot kwenye Ubuntu 24.04 nyuma ya nginx. Ikiwa seva tayari inahudumia programu nyingine kwa kutumia Traefik inayoelekeza programu kadhaa za Compose, ongeza mem0 kwenye router hiyo badala ya kusakinisha proxy ya pili.
Jaribio la moshi: ongeza kumbukumbu moja na uisome tena
export MEM0_KEY='<the ADMIN_API_KEY from .env>'
curl -sS -X POST http://127.0.0.1:8888/memories \
-H "Content-Type: application/json" \
-H "X-API-Key: $MEM0_KEY" \
-d '{"messages":[{"role":"user","content":"I deploy with Docker Compose and I run Postgres 17."}],"user_id":"smoke"}'Jibu sahihi ni kitu cha JSON chenye orodha ya results, na kila ingizo lina id, maandishi ya memory yaliyotolewa, na "event": "ADD". Algorithm ya sasa inarejesha matukio ya ADD pekee. Matukio ya UPDATE na DELETE yaliondolewa, kwa hivyo kutokuwepo kwao si hitilafu.
curl -sS -X POST http://127.0.0.1:8888/search \
-H "Content-Type: application/json" \
-H "X-API-Key: $MEM0_KEY" \
-d '{"query":"which database do I run?","filters":{"user_id":"smoke"},"top_k":5}'Ukweli kuhusu Postgres 17 unapaswa kurejea na alama (score). Pitisha kitambulishi ndani ya filters, kama inavyoonyeshwa. user_id ya kiwango cha juu bado inafanya kazi, na seva huweka kumbukumbu ya Top-level user_id in /search is deprecated. Use filters={...} instead. kila unapoitumia.
Safisha data uliyotumia ili data ya majaribio isichafue utafutaji halisi:
curl -sS -X DELETE "http://127.0.0.1:8888/memories?user_id=smoke" \
-H "X-API-Key: $MEM0_KEY"Ikiwa utafutaji utarejesha safu chache kuliko ulivyotarajia, kagua mipangilio chaguo-msingi kabla ya kulaumu mfumo wa urejeshaji. Katika toleo la sasa, top_k ina thamani chaguo-msingi ya 20, ikishuka kutoka 100, na threshold ina thamani chaguo-msingi ya 0.1 badala ya kutokuwa na thamani, kwa hivyo mechi dhaifu sasa huchujwa kiotomatiki. Mara tu hii inapofanya kazi kupitia curl, endpoints zilezile ndizo unazounganisha kwenye agent, iwe moja kwa moja au kupitia seva ya MCP inayofanya kazi kwenye VPS hiyo hiyo.
Endesha mem0 bila ufunguo wa OpenAI hata kidogo
Anza na kizuizi hiki, kwa sababu utakikuta ndani ya dakika tano za kwanza. Image ya seva inakuja na seti maalum ya maktaba za watoa huduma, na /configure hukataa chochote kilicho nje ya hizo:
LLM provider 'ollama' is not bundled in this image. Bundled providers: openai, anthropic, gemini. To use another provider, install its Python package, rebuild the container, and extend BUNDLED_LLM_PROVIDERS in server/main.py.Huna haja ya kujenga upya kitu chochote. Ollama hutoa API inayooana na OpenAI kwenye /v1, ikijumuisha /v1/chat/completions na /v1/embeddings, na mtoa huduma wa openai wa mem0 hukubali openai_base_url. Elekeza ufunguo huo kwenye Ollama na ukaguzi wa ndani utapita, kwa sababu mtoa huduma huyo ni openai kihalisi. Anwani pekee ndiyo inayobadilika.
Ongeza Ollama kwenye mradi uleule wa Compose:
ollama:
image: ollama/ollama
restart: unless-stopped
networks: [mem0_network]
ports:
- "127.0.0.1:11434:11434"
volumes:
- ollama_models:/root/.ollamaOngeza ollama_models: chini ya ufunguo mkuu wa volumes:, kisha vuta (pull) model moja ya chat na model moja ya embedding:
docker compose up -d ollama
docker compose exec ollama ollama pull llama3.1:8b
docker compose exec ollama ollama pull nomic-embed-textIkiwa Ollama tayari inaendeshwa kwenye host kama unit ya systemd, kama ilivyo katika kuendesha Ollama moja kwa moja kwenye VPS, usielekeze container kwenye 127.0.0.1:11434. Ndani ya container ya mem0, 127.0.0.1 ni container ya mem0 yenyewe. Ipe huduma ya mem0 extra_hosts: ["host.docker.internal:host-gateway"], weka Environment="OLLAMA_HOST=0.0.0.0:11434" kwenye systemd drop-in ili Ollama isikilize kwenye anwani ambayo bridge inaweza kuifikia, na uweke port 11434 ikiwa imefungwa kwenye firewall.
Uliza model ukubwa wa embedding yake kabla ya kusanidi chochote
Hatua hii moja huamua kama utafutaji (retrieval) utafanya kazi au la.
Hifadhi ya pgvector ya mem0 hutengeneza jedwali lake kwa upana maalum wa vector, vector vector(1536), kwa sababu embedding_model_dims hutumia 1536 kama chaguo-msingi, ambalo ni upana wa text-embedding-3-small ya OpenAI. nomic-embed-text hurejesha thamani 768. Hakuna kitu ndani ya mem0 kinacholinganisha namba hizo mbili, kwa hivyo kutolingana huko hujitokeza kutoka kwa Postgres wakati wa insert ya kwanza:
expected 1536 dimensions, not 768Usiweke imani yako kwenye namba iliyo katika aya hii pia. Uliza model:
curl -sS http://127.0.0.1:11434/v1/embeddings \
-H "Content-Type: application/json" \
-d '{"model":"nomic-embed-text","input":"dimension check"}' \
| python3 -c "import json,sys; print(len(json.load(sys.stdin)['data'][0]['embedding']))"Hiyo itachapisha upana ambao mkusanyiko wako lazima utumie. Andika usanidi kwenye faili, kwa sababu kubandika nenosiri la Postgres kupitia shell quoting ndiyo njia ambayo makosa ya uchapaji huingia kwenye production.
{
"vector_store": {
"provider": "pgvector",
"config": {
"host": "postgres",
"port": 5432,
"dbname": "postgres",
"user": "postgres",
"password": "<POSTGRES_PASSWORD from .env>",
"collection_name": "memories_local_768",
"embedding_model_dims": 768
}
},
"llm": {
"provider": "openai",
"config": {
"model": "llama3.1:8b",
"api_key": "ollama",
"openai_base_url": "http://ollama:11434/v1",
"temperature": 0.2
}
},
"embedder": {
"provider": "openai",
"config": {
"model": "nomic-embed-text",
"api_key": "ollama",
"openai_base_url": "http://ollama:11434/v1"
}
}
}curl -sS -X POST http://127.0.0.1:8888/configure \
-H "Content-Type: application/json" \
-H "X-API-Key: $MEM0_KEY" \
-d @config.json
curl -sS http://127.0.0.1:8888/configure -H "X-API-Key: $MEM0_KEY"Wito wa pili husoma usanidi huo tena, ambao ni ukaguzi wa kuona kama uandishi umekamilika. Kisha rudia jaribio la awali la smoke test.
Maelezo manne katika JSON hiyo si dhahiri, na kila moja huvunja kitu fulani ukikosea.
api_key ni string ya ollama, na Ollama hupuuza thamani yake. Haiwezi kuwa tupu, kwa sababu maktaba ya mteja wa OpenAI hutoa hitilafu kabla ya ombi lolote kutoka kwenye mchakato wakati hakuna ufunguo uliowekwa. String yoyote isiyo tupu inafanya kazi.
embedding_model_dims huwekwa kwenye vector store, na kwa makusudi hakuna embedding_dims kwenye embedder. mem0 hutuma kigezo cha dimensions cha OpenAI pale tu unapoweka embedding_dims, na backend ambazo hazitekelezi Matryoshka truncation hukataa kigezo hicho moja kwa moja. Weka upana pale jedwali linapoundwa, na uache embedder peke yake.
collection_name ni mpya. mem0 hutengeneza jedwali lake kwa CREATE TABLE IF NOT EXISTS, kwa hivyo kuelekeza upana tofauti kwenye mkusanyiko uliopo hakufanyi kitu chochote: safu wima ya zamani ya vector(1536) inabaki, na kila insert inafeli. Mabadiliko ya upana yanahitaji jina jipya la mkusanyiko, au ufute jedwali la zamani kwa mkono.
Host katika openai_base_url ni jina la huduma ya Compose ya ollama, si localhost. Container hutatua majina ya kila mmoja kwa kutumia jina la huduma kwenye mtandao wao wa pamoja.
Gharama ya njia ya ndani kabisa (fully local)
Kuwa mkweli kwako mwenyewe kuhusu ubora. Alama za benchmark zilizochapishwa na mem0 zilipimwa kwa kutumia model za hali ya juu (frontier models) kufanya uchimbaji wa data, kwa hivyo zichukulie kama ukomo badala ya utabiri kwa model ya 8B kwenye VPS yako. Model ndogo huandika ukweli usio dhahiri, na wakati mwingine hurejesha maelezo badala ya JSON iliyoombwa, jambo linaloonekana kama wito wa add unaorejesha orodha tupu ya results bila hitilafu.
Kasi ndiyo gharama nyingine. Uchimbaji wa data kwa kutumia CPU pekee huchukua sekunde kwa kila wito wa add, na kila ujumbe unaohifadhi hulipia gharama hiyo. Ikiwa latency hiyo ni muhimu, VPS yenye GPU iliyounganishwa ndiyo suluhisho la kweli. Kuongeza CPU cores zaidi kwenye model ya 8B husaidia kidogo sana kuliko watu wanavyotarajia.
Kanuni moja inabaki bila kujali unachochagua: usichanganye kamwe model za embedding ndani ya mkusanyiko mmoja. Model mbili tofauti ambazo kwa bahati zina upana sawa hutoa vector ambazo haziwezi kulinganishwa. Insert inafanikiwa, utafutaji hurejesha safu, na safu hizo huwa si sahihi, bila kitu chochote kuripoti hitilafu.
Hifadhi rudufu: kuna hifadhidata mbili, si moja
Kosa la kawaida la hifadhi rudufu ya mem0 ni kudump hifadhidata moja pekee. init-db.sh hutengeneza mem0_app sambamba na hifadhidata chaguo-msingi ya postgres, na hizi huhifadhi vitu tofauti. Hifadhidata ya postgres huhifadhi mikusanyiko ya pgvector, ambayo ndiyo kumbukumbu. mem0_app huhifadhi watumiaji, vipindi (sessions), funguo za API na kumbukumbu za maombi (request logs).
Ukirejesha postgres pekee, kumbukumbu zitarudi lakini kila akaunti na ufunguo wa API utapotea, kwa hivyo hakuna kitakachoweza kuthibitisha utambulisho ili kuzisoma. Dump zote mbili, pamoja na roles, kwa amri moja:
docker compose exec -T postgres pg_dumpall -U postgres --clean \
| gzip > "mem0-$(date +%F).sql.gz"Volyumu ya historia ni tofauti na Postgres na inahitaji nakala yake yenyewe:
docker run --rm -v mem0_mem0_history:/data -v "$PWD:/backup" \
alpine tar czf /backup/mem0-history.tgz -C /data .Docker huongeza viambishi awali vya majina ya volyumu kwa jina la mradi, kwa hivyo thibitisha yako kwa docker volume ls kabla ya kudhani ni mem0_mem0_history.
Rejesha kwenye kontena la majaribio (scratch container) na uangalie idadi ya safu (row counts) kabla ya kuamini chochote:
gunzip -c mem0-2026-08-03.sql.gz \
| docker compose exec -T postgres psql -U postgres -d postgresHifadhi rudufu ambayo hujawahi kuirejesha ni kubahatisha tu. Mara tu dumps zinapokuwa sahihi, zihamishe kutoka kwenye seva hiyo kwa restic snapshots kwenda kwenye hifadhi ya nje, kwa sababu hifadhi rudufu inayokaa kwenye seva yenyewe haitoi ulinzi wowote.
Njia za kufeli na ujumbe kamili utakaouona
{"detail":"Authentication required. Provide a Bearer token or X-API-Key header."} inamaanisha kuwa kichwa cha habari (header) hakipo au kimeandikwa vibaya. Jina lake ni X-API-Key, na curl hutuma majina ya header kama yalivyo.
{"detail":"At least one identifier (user_id, agent_id, run_id) is required."} kwenye kitendo cha kuongeza (add) inamaanisha ombi halikuwa na yoyote kati ya hayo. Kumbukumbu lazima iwe na wigo (scope) kwa kitu fulani, kwa sababu vichujio vya utafutaji hufanya kazi kwenye sehemu hizo mahususi.
LLM provider 'ollama' is not bundled in this image pamoja na HTTP 400 inamaanisha umetuma "provider": "ollama". Tumia "provider": "openai" huku openai_base_url ikielekezwa kwenye Ollama.
expected 1536 dimensions, not 768 kutoka Postgres inamaanisha kuwa mkusanyiko (collection) uliundwa kwa upana mmoja na embedder inarejesha mwingine. Weka embedding_model_dims kwenye vector store na utumie collection_name mpya.
Utafutaji unarejesha safu zisizo na maana baada ya kubadilisha modeli, bila kosa lolote. Upana bado unalingana, kwa hivyo hifadhidata inafanya kazi, lakini modeli mbili huweka sentensi moja katika nafasi tofauti. Anzisha mkusanyiko mpya na uongeze data upya.
Connection refused kwenye logi za mem0 wakati wa kufikia Ollama kwa kawaida inamaanisha 127.0.0.1 katika openai_base_url. Ndani ya container, anwani hiyo ni container yenyewe. Tumia jina la huduma, au host gateway wakati Ollama inapoendeshwa kwenye host.
504 Gateway Time-out kutoka nginx kwenye kitendo cha kuongeza inamaanisha kuwa modeli ilichukua muda mrefu kuliko proxy_read_timeout. Ongeza muda huo, na uangalie kama kumbukumbu iliandikwa hata hivyo kabla ya kujaribu ombi hilo tena.
exit code 137 wakati wa docker compose up --build ni kitendo cha out-of-memory killer kusimamisha ujenzi wa dashboard. Ongeza swap, au jenga image kwenye mashine kubwa zaidi kisha uisukume (push) kwenye registry.
error: port 3000 is already in use inatoka kwenye target ya make up ya repo, ambayo inakataa kuanza wakati port 3000 au 8888 zinatumiwa na mwingine. Tafuta mmiliki kwa kutumia lsof -iTCP:3000 -sTCP:LISTEN.
FAQ
Je, bado nahitaji Neo4j ili kuendesha mem0 yenye graph memory?
Hapana. Algorithm mpya ya kumbukumbu, iliyotolewa mwezi Aprili 2026, imeondoa funguo za usanidi za graph_store na enable_graph kutoka kwenye SDK ya chanzo huria. Uchimbaji wa entity sasa hufanyika wakati wa operesheni ya kawaida ya kuongeza data na huandika kwenye mkusanyiko wa pili wa pgvector unaoitwa <collection_name>_entities, kwa hivyo hakuna database ya nje ya graph, hakuna container ya ziada na hakuna hatua ya uhamiaji (migration). Hasara yake ni kwamba uwanja wa relations kwenye matokeo ya utafutaji haupo tena. Entities sasa huongeza kiwango cha umuhimu wa kumbukumbu badala ya kukupa viungo (edges) vya kupitia, kwa hivyo programu iliyokuwa ikitumia mahusiano hayo inahitaji hifadhi yake ya graph nje ya mem0.
Ni VPS ndogo kiasi gani inayoweza kuendesha seva ya mem0 iliyojiendesha (self-hosted)?
Ikiwa language model imehifadhiwa kwingine, 2 GB ya RAM na takriban 4 GB ya nafasi ya diski inatosha kwa API container, Postgres na dashboard. Wakati mgumu ni ujenzi wa kwanza, kwa sababu kukusanya (compiling) dashboard ya Next.js hutumia kumbukumbu nyingi kuliko kuiendesha, na mashine ya 1 GB itasababisha ujenzi kufa kwa exit code 137. Ikiwa Ollama inaendeshwa kwenye seva hiyo hiyo, panga nafasi kwa ajili ya model: model ya 8B yenye 4-bit quantisation inahitaji takriban 6 GB yenyewe, kwa hivyo panga kuwa na 8 GB.
Je, ninaweza kuendesha mem0 bila ufunguo wa OpenAI API?
Ndiyo, kupitia endpoint ya Ollama inayooana na OpenAI. Kuweka "provider": "ollama" kutafeli, kwa sababu picha ya seva (server image) ina maktaba za openai, anthropic na gemini pekee na itarudisha HTTP 400. Badala yake, weka "provider": "openai" na uweke "openai_base_url": "http://ollama:11434/v1" kwa kutumia api_key yoyote isiyo tupu, kwa ajili ya llm na embedder. Ollama hupuuza ufunguo huo, na ukaguzi wa mtoa huduma uliounganishwa hupita kwa sababu mtoa huduma kwa kweli ni openai.
Kwa nini mem0 hairudishi matokeo baada ya kubadili kwenda kwenye local embedding model?
Kwa sababu jedwali la pgvector liliundwa kwa upana usiobadilika. embedding_model_dims ina thamani ya msingi ya 1536, nomic-embed-text inarudisha 768, na Postgres hukataa kuingiza data (insert) kwa expected 1536 dimensions, not 768. mem0 huunda jedwali kwa CREATE TABLE IF NOT EXISTS, kwa hivyo kubadilisha namba pekee hakufanyi chochote kwenye mkusanyiko uliopo. Weka embedding_model_dims kwenye upana halisi wa model yako, thibitisha upana huo kwa kuita /v1/embeddings na kuhesabu thamani inazozirudisha, na upe vector store collection_name mpya kwa wakati mmoja.