cognee Docker & Self-Hosted Deployment

GitHub

Cognee is the open-source AI memory platform for agents. Give your AI agents persistent long-term memory with small models for free

RAW Compose
1. Pull Image (DOCKERHUB) docker pull library/neo4j
2. Docker Run (1-Click Launch) docker run -d --name cognee -p 8000:8000 --restart always neo4j:5.26
3. Podman Run podman run -d --name cognee -p 8000:8000 --restart always neo4j:5.26
4. Skopeo Inspect (Zero-Pull Manifest) skopeo inspect docker://docker.io/library/neo4j:5.26
5. ORAS Pull (OCI Artifact) oras pull neo4j:5.26
6. Compose Deployment docker compose up -d
docker-compose.yml
Download .yml
services:
  cognee:
    container_name: cognee
    restart: always
    # Must exceed the shutdown hook's background-task drain (default 8s,
    # BACKGROUND_DRAIN_TIMEOUT_SECONDS) plus the engine close/WAL checkpoint โ€”
    # raise BOTH together, or the worker is SIGKILLed mid-checkpoint.
    stop_grace_period: 15s
    networks:
      - cognee-network
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      # Source bind mount is for dev reload only; persistence lives in the
      # named volumes below (shared with cognee-mcp, both run as uid 1000).
      - ./cognee:/app/cognee
      - .env:/app/.env:ro
      - cognee_system:/cognee-storage/system
      - cognee_data:/cognee-storage/data
      # Uncomment to allow ingestion of local files from host:
      # - /path/to/your/data:/data
    environment:
      - DEBUG=false # Change to true if debugging
      - ENV=local
      - LOG_LEVEL=INFO
      - SYSTEM_ROOT_DIRECTORY=/cognee-storage/system
      - DATA_ROOT_DIRECTORY=/cognee-storage/data
      # Relational DB configuration โ€” defaults to embedded SQLite. For
      # `--profile postgres` set DB_PROVIDER=postgres and DB_HOST=postgres
      # (the service name) in your environment or .env.
      - DB_PROVIDER=${DB_PROVIDER:-sqlite}
      - DB_HOST=${DB_HOST:-host.docker.internal}
      - DB_PORT=${DB_PORT:-5432}
      - DB_NAME=${DB_NAME:-cognee_db}
      - DB_USERNAME=${DB_USERNAME:-}
      - DB_PASSWORD=${DB_PASSWORD:-}
      # CAUTION: Default '*' allows all origins. Override with specific domains in production.
      - CORS_ALLOWED_ORIGINS=${CORS_ALLOWED_ORIGINS:-*}
      # Password login for the default user. This stack is local, so the
      # well-known dev password is the default: `docker compose up` and the UI
      # at localhost:3000 work with no configuration, the same way the
      # POSTGRES_PASSWORD line in any database image's compose does. Override
      # it here or in the environment. The server sets it once on a default
      # user that has no password yet; it never changes an existing password.
      # Do NOT reuse this value on a server reachable from a network -- there,
      # leave it unset and no default-user login exists.
      - DEFAULT_USER_PASSWORD=${DEFAULT_USER_PASSWORD:-default_password}
    extra_hosts:
      # Allows the container to reach your local machine using "host.docker.internal" instead of "localhost"
      - "host.docker.internal:host-gateway"
    ports:
      - 8000:8000
      - 5678:5678 # Debugger port
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    deploy:
      resources:
        limits:
          cpus: "4.0"
          memory: 8GB

  # Cognee MCP Server - Model Context Protocol server for IDE integration
  cognee-mcp:
    container_name: cognee-mcp
    profiles:
      - mcp
    networks:
      - cognee-network
    build:
      context: .
      dockerfile: cognee-mcp/Dockerfile
    command: --no-migration
    volumes:
      - .env:/app/.env:ro
      - ./cognee:/app/cognee
      # Same storage volumes as the main service: shared memory between the
      # API and the MCP server is the point of running both (same uid 1000).
      - cognee_system:/cognee-storage/system
      - cognee_data:/cognee-storage/data
      # Uncomment to allow ingestion of local files from host:
      # - /path/to/your/data:/data
    environment:
      - DEBUG=false # Change to true if debugging
      - ENV=local
      - LOG_LEVEL=INFO
      - SYSTEM_ROOT_DIRECTORY=/cognee-storage/system
      - DATA_ROOT_DIRECTORY=/cognee-storage/data
      # Streamable HTTP rather than the legacy sse transport. Endpoint: /mcp.
      # The container binds 0.0.0.0, so the Host/Origin (DNS-rebinding) guard
      # rejects requests arriving by LAN IP or a custom hostname with HTTP 421
      # by design; allow them explicitly with
      # MCP_ALLOWED_HOSTS=192.168.1.50:*,myhost.local:* (the ":*" port glob is
      # required), or MCP_DISABLE_DNS_REBINDING_PROTECTION=true to turn it off.
      - TRANSPORT_MODE=http
      # Database configuration - should match the main cognee service
      - DB_PROVIDER=${DB_PROVIDER:-sqlite}
      - DB_HOST=${DB_HOST:-host.docker.internal}
      - DB_PORT=${DB_PORT:-5432}
      - DB_NAME=${DB_NAME:-cognee_db}
      - DB_USERNAME=${DB_USERNAME:-}
      - DB_PASSWORD=${DB_PASSWORD:-}
      # MCP specific configuration
      - PYTHONUNBUFFERED=1
    extra_hosts:
      - "host.docker.internal:host-gateway"
    ports:
      # Host ports differ from the main `cognee` service so both can run together
      # (the MCP server still listens on 8000 inside the container).
      - "8001:8000" # MCP port
      - "5679:5678" # MCP debugger port
    healthcheck:
      # The MCP runtime image is python-slim (no curl), so probe with urllib.
      test: ["CMD", "python", "-c", "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://localhost:8000/health', timeout=5).status==200 else 1)"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    deploy:
      resources:
        limits:
          cpus: "2.0"
          memory: 4GB

  # cognee UI. `--profile ui` runs the published image, so a user without the
  # repo gets the same thing CI publishes; `--profile ui-dev` builds the
  # hot-reloading stage from source for frontend work.
  #
  # NOTE: the UI is a work in progress and covers the minimum set of features
  # needed to be functional. For a richer experience you can also integrate the
  # cognee MCP server into Cursor / Claude Desktop / VS Code (through Cline/Roo).
  frontend:
    container_name: frontend
    restart: always
    image: cognee/cognee-ui:${COGNEE_UI_TAG:-latest}
    profiles:
      - ui
    environment:
      # Empty means "derive it from the address the browser used", which is
      # correct for the default localhost setup. The browser talks to the
      # backend directly, so when you do set this it must be the address as
      # seen from the browser, not the `cognee` service name.
      - COGNEE_BACKEND_URL=${COGNEE_BACKEND_URL:-}
      # Same value as the backend's: the UI's server-side routes fall back to a
      # default-user login when the browser sent no credentials.
      - DEFAULT_USER_PASSWORD
    depends_on:
      cognee:
        condition: service_healthy
    ports:
      - 3000:3000
    networks:
      - cognee-network

  frontend-dev:
    container_name: frontend-dev
    restart: always
    profiles:
      - ui-dev
    build:
      context: ./cognee-frontend
      dockerfile: Dockerfile
      target: dev
    environment:
      - COGNEE_BACKEND_URL=${COGNEE_BACKEND_URL:-}
      - DEFAULT_USER_PASSWORD
    volumes:
      - ./cognee-frontend/src:/app/src
      - ./cognee-frontend/public:/app/public
    ports:
      - 3000:3000
      # - 9229:9229 # Debugging
    networks:
      - cognee-network

  neo4j:
    image: neo4j:5.26  # Pinned to 5.x; compatible with neo4j Python driver >=5.28,<6
    container_name: neo4j
    restart: always
    profiles:
      - neo4j
    ports:
      - 7474:7474
      - 7687:7687
    environment:
      - NEO4J_AUTH=neo4j/pleaseletmein
      - NEO4J_PLUGINS=["apoc", "graph-data-science"]
    networks:
      - cognee-network

  postgres:
    image: pgvector/pgvector:pg17
    container_name: postgres
    restart: always
    profiles:
      - postgres
    environment:
      POSTGRES_USER: cognee
      POSTGRES_PASSWORD: cognee
      POSTGRES_DB: cognee_db
    # Persist data on a named volume so it survives container recreate. The
    # docker-compose e2e (test_postgres_persistence_across_recreate) depends on
    # this โ€” without it, a recreated postgres container starts empty.
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - 5432:5432
    networks:
      - cognee-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U cognee -d cognee_db"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s

  redis:
    image: redis:7-alpine
    container_name: redis
    profiles:
      - redis
    ports:
      - "6379:6379"
    networks:
      - cognee-network
    volumes:
      - redis_data:/data
    command: [ "redis-server", "--appendonly", "yes" ]


  redisinsight:
    image: redislabs/redisinsight:latest
    container_name: redisinsight
    restart: always
    ports:
      - "5540:5540"
    networks:
      - cognee-network


networks:
  cognee-network:
    name: cognee-network

volumes:
  cognee_system:
  cognee_data:
  postgres_data:
  redis_data: