SSD Nodes Learn 🎉 VPS $4.99/aydan başlayan
Rehberler Matt ConnorYazan Matt Connor · Güncellendi 2026-08-07

Kendi VPS Sunucunuzda mem0 Kurulumu ve RAM Gereksinimleri

Kendi VPS sunucunuzda mem0 barındırmak için gereken gerçek RAM miktarı, Docker Compose yapılandırması, TLS kurulumu ve Ollama ile yerel bellek yönetimi hakkında detaylı rehber.

Bir VPS üzerinde mem0 barındırmanın gerçek RAM maliyeti

mem0'ı kendi sunucunuzda barındırmak, üç container çalıştırmak anlamına gelir: FastAPI bellek sunucusu, pgvector eklentili Postgres ve bir Next.js paneli. mem0, yapay zeka ajanları için bir bellek katmanıdır. Bir konuşmayı buraya gönderdiğinizde, bir dil modeli bu konuşmadan kalıcı gerçekleri çıkarır ve bu gerçekler, daha sonraki sorguların ilgili olanları geri getirebilmesi için vektör olarak saklanır.

Üç container için yaklaşık 1 GB yerleşik bellek (resident memory) ve imajlar oluşturulduktan sonra 3 ila 4 GB disk alanı ayırın. Dil modeli başka bir yerde çalıştığında, 2 GB RAM'e sahip bir VPS bu kurulumu rahatlıkla çalıştırır. Model, Ollama aracılığıyla aynı sunucuda çalıştırıldığında, model diğer her şeyin önüne geçer: 4 bit kuantize edilmiş 8B bir model tek başına yaklaşık 6 GB RAM gerektirir, bu nedenle tamamen yerel bir kurulum 8 GB RAM ile başlar.

Bu rakamları, bu yazı da dahil olmak üzere herhangi bir blog gönderisinden olduğu gibi almayın. Kendi kurduğunuz yığını ölçün.

docker compose ps
docker stats --no-stream
docker system df -v

docker stats, container başına düşen yerleşik belleği yazdırır. docker system df -v, her imajın ve her birimin kapladığı disk alanını yazdırır.

Kararlı durum (steady state), en yüksek kullanım anı değildir. docker compose up -d --build, Next.js panelini derler ve bu Node derleme süreci, kurulumun en çok kaynak tüketen anıdır. 1 GB RAM'e sahip bir VPS üzerinde çekirdeğin bellek yetersizliği sonlandırıcısı (OOM killer) bu süreci durdurur ve derleme exit code 137 hatasıyla sona erer. Bir Docker hatası aramaya başlamadan önce nedeni doğrulayın:

dmesg -T | grep -i "killed process"

Eğer bir sunucu, ihtiyacınız olan şey için çok fazla donanım gerektiriyorsa, daha küçük seçenekler mevcuttur. hiç sunucu gerektirmeyen yerel bir ajan bellek deposu ve doğrudan Claude Code içinde yaşayan bellek, veritabanı ihtiyacını ortadan kaldırır. Birden fazla ajan veya birden fazla makine aynı bellekleri okumaya ihtiyaç duyduğunda buraya geri dönün.

mem0 grafik belleği için Neo4j gerekli mi?

Hayır. Eğer bir kılavuz size bir Neo4j container'ı eklemenizi söylüyorsa, o kılavuz koddan daha eskidir.

mem0 içindeki grafik belleği, eskiden graph_store anahtarı altında yapılandırılan ve enable_graph değeri true olarak ayarlanan harici bir grafik veritabanı anlamına geliyordu. Nisan 2026'da yayınlanan yeni bellek algoritması, her iki anahtarı da açık kaynaklı SDK'dan kaldırdı. Varlık çıkarma işlemi artık normal add yolu içinde çalışır ve varlıklar, ana koleksiyonunuzun adını taşıyan ve sonuna _entities eklenmiş ikinci bir pgvector koleksiyonuna yazılır. Çalıştırılması gereken bir taşıma işlemi yoktur. Yerleşik varlık bağlama özelliği, bir sonraki add çağrısında çalışmaya başlar.

Grafik deposunu kaldırmak, bir JVM container'ını, onun heap alanını ve birkaç yüz megabaytlık imaj boyutunu tasarruf etmenizi sağlar. 2 GB RAM'e sahip bir VPS üzerinde bu, sistemin çalışması ile swap alanına düşmesi arasındaki farktır.

Açıkça belirtmek gerekirse, vazgeçtikleriniz şunlardır: Arama sonuçları eskiden varlıklar arasındaki kenarları listeleyen bir relations alanı taşıyordu. Bu alan artık kaldırıldı. Varlık eşleşmeleri artık bir belleğin konumunu birleşik puan içinde yükseltir ve üzerinde gezinebileceğiniz bir yapı yoktur. Uygulamanız bu ilişkiler üzerinde geziniyorsa, mem0 artık bunları tutmaz; bu durumda kendi kodunuzla beslediğiniz, mem0 dışında kendi grafik veritabanınızı kullanmaya devam etmeniz gerekir.

Depodaki compose dosyası bir geliştirme ortamı compose dosyasıdır

server/docker-compose.yaml, name: mem0-dev değerini tanımlar ve bu durum tam olarak ifade edildiği anlama gelir. Çalıştırmadan önce içeriğini okuyun, çünkü dosya içerisinde sunucu ortamı için hatalı olan beş nokta bulunmaktadır.

  • Dosya, server/dev.Dockerfile üzerinden derleme yapar ve .:/app ile yerel dizininizi imajın üzerine bağlar (mount); bu nedenle container, derlediğiniz kodu değil, o dizinde o an ne varsa onu çalıştırır.
  • Komutu rm -rf /app/packages && pip install -q --force-reinstall --no-deps mem0ai && alembic upgrade head && uvicorn main:app --reload şeklindedir. Bu komut, her başlatmada mem0ai paketini PyPI üzerinden yeniden kurar; dolayısıyla sunucunuzun çalıştırdığı sürüm, yükseltme yapmadığınızı düşündüğünüz bir yeniden başlatma sırasında değişebilir.
  • Aynı pip adımı, dış ağ bağlantısı olmayan bir yeniden başlatmanın uvicorn çalışmadan önce başarısız olacağı anlamına gelir. PyPI erişilemez olduğu için bellek sunucunuz devre dışı kalır.
  • --reload, uvicorn'un dosya izleyicisini başlatır. Bu özellik, kod düzenlediğinizde süreci yeniden başlatmak için vardır; üretim ortamında hiçbir işe yaramaz ve ek bellek tüketimi ile fazladan bir süreç oluşturur. Üretim ortamındaki Dockerfile de CMD içerisinde --reload barındırır, bu yüzden komutu her iki durumda da geçersiz kılarsınız.
  • Yayınlanan portlar "8888:8000", "8432:5432" ve "3000:3000" şeklindedir. Önünde bir adres belirtilmeyen yayınlanmış bir port 0.0.0.0 adresine bağlanır; bu nedenle yığın başladığı anda Postgres, 8432 portu üzerinden genel internete yanıt verir.

Bu son nokta, kendi başına bir uyarıyı hak etmektedir. Docker, kendi kurallarını ufw tarafından yönetilen zincirin önüne yazarak bir portu yayınlar; bu yüzden ufw deny 8432, yayınlanmış bir container portunu kapatmaz. Docker'ın ufw kurallarını atlayarak port yayınlaması belgesi, ilgili kuralların işleyişini detaylandırmaktadır.

Gerçek bir sunucu için compose dosyası

server/ içinde çalışın, init-db.sh öğesini olduğu yerde tutun ve docker-compose.yaml kısmını bununla değiştirin.

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: bridge

Burada beş değişiklik önemlidir ve her birinin bir nedeni vardır.

Her ports girdisi 127.0.0.1 ile başlar, böylece çekirdek bu bağlantıları yalnızca sunucunun kendisinden kabul eder. Dışarıdan gelen her şey, sertifikayı tutan tek bileşen olan reverse proxy üzerinden ulaşır.

Postgres içinde hiçbir ports bloğu bulunmaz. mem0 container'ı, ona mem0_network üzerinden servis adıyla ulaşır; bu nedenle 8432 portunu dışarı açmak size bir şey kazandırmaz, aksine açık bir port maliyeti getirir. Bir shell'e ihtiyaç duyduğunuzda docker compose exec postgres psql -U postgres kullanın.

Geçmiş verisi, ./history bind mount'undan adlandırılmış bir volume'e taşınır. Bind mount, veriyi bu ana makinedeki tek bir yola ve tek bir uid'ye bağlarken, adlandırılmış volume Docker'ın snapshot alabileceği ve taşıyabileceği bir nesnedir. Named volumes against bind mounts makalesi, hangisinin ne zaman doğru tercih olduğunu açıklar.

Komut --reload kısmını çıkarır ve alembic upgrade head kısmını tutar. Bu migration adımını koruyun. Bu adım olmadan uygulama, tabloları olmayan bir veritabanına karşı başlatılır ve her istek ilk sorguda başarısız olur.

NEXT_PUBLIC_API_URL, tarayıcınızın çağırdığı URL'dir; bu nedenle http://mem0:8000 değil, herkese açık HTTPS adresi olmalıdır. Next.js her NEXT_PUBLIC_ değerini build zamanında içine gömer (inline eder), bu yüzden bunu değiştirmek docker compose up -d --build mem0-dashboard gerektirir. Basit bir yeniden başlatma, eski değerin JavaScript içine gömülü kalmasına neden olur ve dashboard yanlış host'u çağırır. Sırada ne var.

Gizli veriler .env dosyasında tutulur ve .env internete kapalı kalmalıdır

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 .env

POSTGRES_PASSWORD, JWT_SECRET ve ADMIN_API_KEY ayarlarını yapılandırın. AUTH_DISABLED=false ayarını olduğu gibi bırakın. Bu bayrağın ismi işlevini açıkça belirtir: etkinleştirildiğinde sunucu, porta erişebilen herkese belleğindeki tüm verileri sunar. Onboarding etkinliğinin yukarı yöne (upstream) gönderilmesini istemiyorsanız MEM0_TELEMETRY=false ayarını yapılandırın.

ADMIN_API_KEY, secrets.compare_digest kullanılarak X-API-Key başlığı ile karşılaştırılır ve eşleşme durumunda veritabanı sorgusu atlanır. Bu, tüm API için bir root kimlik bilgisidir. Buna uygun davranın: shell geçmişine kaydetmeyin, git üzerinde tutmayın ve herhangi bir komut satırına yapıştırmayın. Compose env dosyaları ve içlerindeki gizli verilerin sızdığı noktalar ve API anahtarlarını bir ajanın bağlamından uzak tutmak başlıklarının her ikisi de doğrudan geçerlidir, çünkü bu sunucunun çağırıcıları ajanlardır.

env_file dosyasından yüklenen değerler container ortamında yer alır ve docker inspect bunları tam olarak yazdırır. docker grubundaki herkes bunları okuyabilir ve docker grubundaki herkes ana makine üzerinde fiilen root yetkisine sahiptir.

API'yi 8888 portunu açmak yerine TLS arkasına alın

API 127.0.0.1:8888 adresinde, dashboard ise 127.0.0.1:3000 adresinde yanıt verir. nginx, 443 portunda TLS (transport layer security) sonlandırmasını gerçekleştirir ve trafiği her ikisine de yönlendirir.

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 göründüğünden daha önemlidir. Bir ekleme çağrısı, dil modeli konuşmayı okuyup gerçekleri çıkarırken engellenir (block). CPU üzerinde çalışan yerel bir 8B model, genellikle nginx'in 60 saniyelik varsayılan süresinden daha uzun sürer; bu durumda model hala çalışırken ve bellek yazılmaya devam ederken arayan taraf 504 Gateway Time-out hatasını görür. Sonuç olarak, başarısız olduğu bildirilen bir bellek kaydıyla karşılaşırsınız.

Geri kalan portları varsayılan bir deny ufw politikası ile kapatın, yalnızca 22 ve 443 portlarını açık bırakın. Sertifikayı Ubuntu 24.04 üzerinde nginx arkasında certbot kullanarak oluşturun. Eğer sunucu halihazırda birden fazla Compose uygulamasını yönlendiren Traefik ile diğer uygulamalara hizmet veriyorsa, ikinci bir proxy kurmak yerine mem0'ı mevcut yönlendiriciye ekleyin.

Smoke testi: bir bellek ekleyin ve geri okuyun

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"}'

Sağlıklı bir yanıt, bir results listesi içeren JSON nesnesidir; her girdi bir id, ayıklanmış memory metni ve "event": "ADD" değerini tutar. Mevcut algoritma yalnızca ADD olaylarını döndürür. UPDATE ve DELETE olayları kaldırılmıştır, bu nedenle bunların yokluğu bir hata değildir.

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}'

Postgres 17 hakkındaki gerçek, bir puan ile geri dönmelidir. Tanımlayıcıyı, gösterildiği gibi filters içine iletin. Üst düzey bir user_id hala çalışır ve sunucu, onu her kullandığınızda Top-level user_id in /search is deprecated. Use filters={...} instead. kaydını tutar.

Test verilerinin gerçek aramaları kirletmemesi için temizlik yapın:

curl -sS -X DELETE "http://127.0.0.1:8888/memories?user_id=smoke" \
  -H "X-API-Key: $MEM0_KEY"

Arama beklediğinizden daha az satır döndürürse, geri almayı suçlamadan önce varsayılan değerleri kontrol edin. Mevcut sürümde top_k varsayılan olarak 100 yerine 20'dir ve threshold hiçbiri yerine 0.1 olarak ayarlanmıştır, bu nedenle zayıf eşleşmeler artık sizin için filtrelenmektedir. Bu işlem curl üzerinden çalıştığında, aynı uç noktalar, doğrudan veya aynı VPS üzerinde çalışan bir MCP sunucusu aracılığıyla bir aracıya bağlayacağınız uç noktalardır.

Hiç OpenAI anahtarı olmadan mem0 çalıştırma

İlk beş dakika içinde karşılaşacağınız engel ile başlayın. Sunucu imajı sabit bir sağlayıcı kütüphanesi setiyle gelir ve /configure bunların dışındaki her şeyi reddeder:

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.

Hiçbir şeyi yeniden derlemeniz gerekmez. Ollama, /v1 adresinde OpenAI uyumlu bir API sunar; bu API /v1/chat/completions ve /v1/embeddings kapsamını karşılar ve mem0'ın openai sağlayıcısı bir openai_base_url kabul eder. Bu anahtarı Ollama'ya yönlendirin; sağlayıcı aslında openai olduğu için paketlenmiş kontrol başarılı olacaktır. Yalnızca adres değişir.

Ollama'yı aynı Compose projesine ekleyin:

  ollama:
    image: ollama/ollama
    restart: unless-stopped
    networks: [mem0_network]
    ports:
      - "127.0.0.1:11434:11434"
    volumes:
      - ollama_models:/root/.ollama

Üst düzey volumes: anahtarının altına ollama_models: ekleyin, ardından bir sohbet modeli ve bir gömme (embedding) modeli çekin:

docker compose up -d ollama
docker compose exec ollama ollama pull llama3.1:8b
docker compose exec ollama ollama pull nomic-embed-text

Ollama halihazırda ana makinede bir systemd birimi olarak çalışıyorsa (bkz: Ollama'yı doğrudan bir VPS üzerinde çalıştırma), konteyneri 127.0.0.1:11434 adresine yönlendirmeyin. mem0 konteyneri içinde 127.0.0.1, mem0 konteynerinin kendisidir. mem0 servisine extra_hosts: ["host.docker.internal:host-gateway"] verin, Ollama'nın köprü ağının erişebileceği bir adreste dinleme yapması için bir systemd drop-in dosyasına Environment="OLLAMA_HOST=0.0.0.0:11434" ayarını ekleyin ve 11434 numaralı portu güvenlik duvarında kapalı tutun.

Herhangi bir yapılandırma yapmadan önce modele gömme boyutunu sorun

Bu tek adım, geri getirmenin (retrieval) çalışıp çalışmayacağını belirler.

mem0'ın pgvector deposu, tablosunu sabit bir vektör genişliği olan vector vector(1536) ile oluşturur; çünkü embedding_model_dims varsayılan olarak OpenAI'ın text-embedding-3-small genişliği olan 1536 değerini kullanır. nomic-embed-text ise 768 değer döndürür. mem0 içinde bu iki sayıyı karşılayan bir mekanizma yoktur, bu nedenle uyumsuzluk ilk ekleme (insert) sırasında Postgres'ten gelen hata ile ortaya çıkar:

expected 1536 dimensions, not 768

Bu paragraftaki sayıya da güvenmeyin. Modele sorun:

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']))"

Bu komut, koleksiyonunuzun kullanması gereken genişliği yazdırır. Yapılandırmayı bir dosyaya yazın; çünkü bir Postgres şifresini kabuk tırnakları üzerinden yapıştırmak, üretim ortamında yazım hatalarına yol açar.

{
  "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"

İkinci çağrı yapılandırmayı geri okur; bu, yazma işleminin başarılı olduğunu doğrulayan kontroldür. Ardından yukarıdaki duman testini (smoke test) tekrarlayın.

Bu JSON içindeki dört detay belirgin değildir ve yanlış yapıldığında her biri bir şeyi bozar.

api_key, ollama dizgisidir ve Ollama bu değerin içeriğini görmezden gelir. Boş olamaz, çünkü OpenAI istemci kütüphanesi herhangi bir anahtar ayarlanmadığında süreçten hiçbir istek çıkmadan önce hata verir. Boş olmayan herhangi bir dizgi çalışır.

embedding_model_dims, vektör deposu üzerinde kullanılır ve gömme motorunda (embedder) kasıtlı olarak embedding_dims yoktur. mem0, OpenAI dimensions parametresini yalnızca embedding_dims ayarlandığında gönderir ve Matryoshka kırpma işlemini uygulamayan arka uçlar bu parametreyi doğrudan reddeder. Genişliği tablonun oluşturulduğu yerde ayarlayın ve gömme motorunu olduğu gibi bırakın.

collection_name yenidir. mem0 tablosunu CREATE TABLE IF NOT EXISTS ile oluşturur, bu nedenle mevcut bir koleksiyona farklı bir genişlik işaret etmek hiçbir işe yaramaz: eski vector(1536) sütunu kalır ve her ekleme işlemi başarısız olur. Genişlik değişikliği için yeni bir koleksiyon adı gerekir veya eski tabloyu elle silmeniz gerekir.

openai_base_url içindeki ana makine, localhost değil, Compose servis adı olan ollama değeridir. Konteynerler, paylaşılan ağları üzerinde birbirlerini servis adlarıyla çözerler.

Tamamen yerel yolun size maliyeti

Kalite konusunda kendinize karşı dürüst olun. mem0'ın yayınlanan kıyaslama puanları, çıkarım işlemini yapan öncü modellerle ölçülmüştür; bu nedenle bunları VPS'nizdeki 8B'lik bir model için bir tahmin değil, bir tavan değeri olarak görün. Küçük bir model daha belirsiz gerçekler yazar ve bazen JSON istendiğinde düz metin döndürür; bu durum, bir ekleme çağrısının hata vermeden boş bir results listesi döndürmesiyle kendini gösterir.

Hız diğer maliyettir. Sadece CPU ile çıkarım yapmak, her ekleme çağrısı için saniyeler sürer ve depoladığınız her mesaj bu maliyeti öder. Eğer bu gecikme önemliyse, GPU takılı bir VPS dürüst çözümdür. 8B'lik bir modele daha fazla CPU çekirdeği vermek, insanların beklediğinden çok daha az yardımcı olur.

Ne seçerseniz seçin tek bir kural geçerlidir: aynı koleksiyon içinde asla farklı gömme modellerini karıştırmayın. Tesadüfen aynı genişliğe sahip olan iki farklı model, karşılaştırılamaz vektörler üretir. Ekleme başarılı olur, arama satırları getirir ancak satırlar yanlıştır ve hiçbir yerde bir hata raporlanmaz.

Yedeklemeler: tek değil, iki veritabanı vardır

En yaygın mem0 yedekleme hatası, tek bir veritabanının yedeğini almaktır. init-db.sh, varsayılan postgres veritabanının yanında mem0_app oluşturur ve bunlar farklı veriler barındırır. postgres veritabanı, bellekleri oluşturan pgvector koleksiyonlarını tutar. mem0_app ise kullanıcıları, oturumları, API anahtarlarını ve istek günlüklerini barındırır.

Yalnızca postgres geri yüklendiğinde bellekler geri gelir ancak tüm hesaplar ve API anahtarları kaybolur; bu nedenle hiçbir şey kimlik doğrulaması yapıp onları okuyamaz. Her ikisini ve rolleri tek bir komutla dışa aktarın:

docker compose exec -T postgres pg_dumpall -U postgres --clean \
  | gzip > "mem0-$(date +%F).sql.gz"

Geçmiş (history) birimi Postgres'ten ayrıdır ve kendi kopyasına ihtiyaç duyar:

docker run --rm -v mem0_mem0_history:/data -v "$PWD:/backup" \
  alpine tar czf /backup/mem0-history.tgz -C /data .

Docker, birim isimlerinin başına proje adını ekler; bu nedenle mem0_mem0_history varsayımında bulunmadan önce docker volume ls ile kendi birim isimlerinizi doğrulayın.

Verileri bir scratch container içine geri yükleyin ve herhangi bir işleme güvenmeden önce satır sayılarını kontrol edin:

gunzip -c mem0-2026-08-03.sql.gz \
  | docker compose exec -T postgres psql -U postgres -d postgres

Geri yüklemesini hiç denemediğiniz bir yedekleme, sadece bir tahmindir. Dökümler doğru olduğunda, bunları sunucu dışı depolama alanına restic anlık görüntüleri ile gönderin; çünkü koruduğu sunucuda duran bir yedekleme hiçbir şeyi korumaz.

Hata modları ve göreceğiniz kesin dizeler

{"detail":"Authentication required. Provide a Bearer token or X-API-Key header."} ifadesi, başlığın eksik veya yanlış yazılmış olduğu anlamına gelir. İsim X-API-Key şeklindedir ve curl, başlık isimlerini olduğu gibi gönderir.

Bir ekleme işleminde {"detail":"At least one identifier (user_id, agent_id, run_id) is required."} hatası, istekte bunlardan hiçbirinin bulunmadığını belirtir. Arama filtreleri tam olarak bu alanlar üzerinde çalıştığı için bir belleğin belirli bir kapsama sahip olması gerekir.

HTTP 400 ile birlikte LLM provider 'ollama' is not bundled in this image hatası, "provider": "ollama" gönderdiğiniz anlamına gelir. openai_base_url ile Ollama'ya yönlendirilmiş "provider": "openai" kullanın.

Postgres'ten gelen expected 1536 dimensions, not 768 hatası, koleksiyonun bir genişlikte oluşturulduğunu ancak gömücünün (embedder) başka bir genişlik döndürdüğünü gösterir. Vektör deposunda embedding_model_dims ayarını yapın ve yeni bir collection_name kullanın.

Arama, model değişikliğinden sonra anlamsız satırlar döndürür ve hiçbir yerde hata oluşmaz. Genişlik hala eşleştiği için veritabanı işlemden memnundur, ancak iki farklı model aynı cümleyi farklı konumlara yerleştirir. Yeni bir koleksiyon başlatın ve verileri yeniden ekleyin.

Ollama'ya erişirken mem0 günlüklerinde görülen Connection refused, genellikle openai_base_url içindeki 127.0.0.1 anlamına gelir. Container içinde bu adres, container'ın kendisidir. Servis ismini veya Ollama ana makinede (host) çalışıyorsa host gateway adresini kullanın.

Bir ekleme işleminde nginx'ten gelen 504 Gateway Time-out, modelin proxy_read_timeout süresinden daha uzun sürdüğü anlamına gelir. Bu süreyi artırın ve isteği yeniden denemeden önce belleğin zaten yazılıp yazılmadığını kontrol edin.

docker compose up --build sırasında oluşan exit code 137, dashboard derlemesini durduran bellek yetersizliği (OOM killer) hatasıdır. Swap alanı ekleyin veya imajı daha büyük bir makinede derleyip bir kayıt defterine (registry) gönderin.

error: port 3000 is already in use, 3000 veya 8888 numaralı portlar kullanımdayken başlatılmayı reddeden deponun make up hedefinden kaynaklanır. lsof -iTCP:3000 -sTCP:LISTEN komutuyla portu kullanan süreci bulun.

FAQ

Grafik belleği ile mem0 çalıştırmak için hala Neo4j'ye ihtiyacım var mı?

Hayır. Nisan 2026'da yayınlanan yeni bellek algoritması, açık kaynaklı SDK içerisinden graph_store ve enable_graph yapılandırma anahtarlarını kaldırdı. Varlık çıkarımı artık normal bir ekleme işlemi sırasında çalışır ve <collection_name>_entities adında ikinci bir pgvector koleksiyonuna yazılır; bu nedenle harici bir grafik veritabanı, ek bir container veya geçiş adımı gerekmez. Bunun karşılığında, arama sonuçlarındaki relations alanı artık mevcut değildir. Varlıklar artık üzerinde gezinebileceğiniz kenarlar sağlamak yerine bir belleğin sıralama değerini yükseltir; bu nedenle bu ilişkiler üzerinde gezinen bir uygulamanın mem0 dışında kendi grafik deposuna ihtiyacı vardır.

Kendi sunucumda mem0 çalıştırmak için gereken en küçük VPS nedir?

Dil modeli başka bir yerde barındırılıyorsa, API container'ı, Postgres ve dashboard için 2 GB RAM ve yaklaşık 4 GB boş disk alanı yeterlidir. En kritik an ilk derleme aşamasıdır; çünkü Next.js dashboard'unu derlemek, çalıştırmaktan daha fazla bellek tüketir ve 1 GB'lık bir sunucuda derleme işlemi exit code 137 hatasıyla sonlandırılır. Eğer Ollama aynı sunucuda çalışacaksa, modeli de hesaba katın: 4-bit kuantizasyonlu 8B bir model tek başına yaklaşık 6 GB bellek gerektirir, bu yüzden 8 GB RAM planlayın.

mem0'ı OpenAI API anahtarı olmadan çalıştırabilir miyim?

Evet, Ollama'nın OpenAI uyumlu uç noktası üzerinden çalıştırabilirsiniz. "provider": "ollama" ayarını yapmak başarısız olur, çünkü sunucu imajı yalnızca openai, anthropic ve gemini kütüphanelerini içerir ve HTTP 400 hatası döndürür. Bunun yerine "provider": "openai" değerini koruyun ve hem llm hem de embedder için "openai_base_url": "http://ollama:11434/v1" ayarını boş olmayan herhangi bir api_key ile yapılandırın. Ollama bu anahtarı görmezden gelir ve sağlayıcı gerçekten openai olduğu için paketlenmiş sağlayıcı kontrolü başarıyla geçer.

Yerel bir embedding modeline geçtikten sonra mem0 neden sonuç döndürmüyor?

Çünkü pgvector tablosu sabit bir genişlikte oluşturulmuştur. embedding_model_dims varsayılan olarak 1536 değerini kullanır, nomic-embed-text ise 768 döndürür ve Postgres ekleme işlemini expected 1536 dimensions, not 768 hatasıyla reddeder. mem0 tabloyu CREATE TABLE IF NOT EXISTS ile oluşturur, bu nedenle sadece sayıyı değiştirmek mevcut koleksiyon üzerinde bir etki yaratmaz. embedding_model_dims değerini modelinizin gerçek genişliğine ayarlayın, /v1/embeddings komutunu çağırıp döndürdüğü değerleri sayarak bu genişliği doğrulayın ve aynı anda vektör deposuna yeni bir collection_name verin.

#mem0#agent-memory#docker#self-hosting#ollama