> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognee.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Docker Deployment

> Deploy Cognee and its supporting services using Docker Compose profiles

Deploy Cognee locally or on a server with Docker Compose. The included `docker-compose.yml` uses **profiles** so you can start only the services you need.

## Prerequisites

* [Docker](https://docs.docker.com/get-docker/) and Docker Compose v2+
* Git

## Quick Start

```bash theme={null}
git clone https://github.com/topoteretes/cognee.git
cd cognee
cp .env.template .env
```

Edit `.env` and set your LLM API key:

```bash theme={null}
LLM_API_KEY="your_api_key"
```

Then start the Cognee API server (no profile needed):

```bash theme={null}
docker compose up --build cognee
```

The API will be available at `http://localhost:8000`. Interactive docs at `http://localhost:8000/docs`.

## Service Profiles

Each optional service is gated behind a profile. Use `--profile` to activate one or more:

| Profile    | Service      | Port(s)        | Purpose                         |
| ---------- | ------------ | -------------- | ------------------------------- |
| *(none)*   | `cognee`     | `8000`, `5678` | Core API server                 |
| `mcp`      | `cognee-mcp` | `8000`, `5678` | MCP server for IDE integrations |
| `ui`       | `frontend`   | `3000`         | Experimental web UI             |
| `neo4j`    | `neo4j`      | `7474`, `7687` | Neo4j graph database            |
| `chromadb` | `chromadb`   | `3002`         | ChromaDB vector database        |
| `postgres` | `postgres`   | `5432`         | PostgreSQL + pgvector           |
| `redis`    | `redis`      | `6379`         | Redis caching                   |

## Data Persistence

The compose file mounts your local `cognee/` source directory and `.env` file into the container. Named volumes persist database data between restarts:

| Service    | Volume                        |
| ---------- | ----------------------------- |
| `postgres` | `postgres_data`               |
| `chromadb` | `.chromadb_data/` (local dir) |
| `redis`    | `redis_data`                  |

To ingest files from your host machine, uncomment and update the volume in `docker-compose.yml`.

```yaml theme={null}
# - /path/to/your/data:/data
```

## Environment Variables

The `cognee` container reads configuration from `.env` at startup. Key variables:

| Variable                      | Default              | Description                                                                                    |
| ----------------------------- | -------------------- | ---------------------------------------------------------------------------------------------- |
| `LLM_API_KEY`                 | *(required)*         | API key for your LLM provider                                                                  |
| `LLM_MODEL`                   | `openai/gpt-4o-mini` | LLM model to use                                                                               |
| `DB_PROVIDER`                 | `sqlite`             | Relational DB: `sqlite` or `postgres`                                                          |
| `GRAPH_DATABASE_PROVIDER`     | `kuzu`               | Graph DB: `kuzu`, `neo4j`, etc.                                                                |
| `VECTOR_DB_PROVIDER`          | `lancedb`            | Vector DB: `lancedb`, `chromadb`, `pgvector`, etc.                                             |
| `CORS_ALLOWED_ORIGINS`        | `*`                  | Restrict to specific domains in production                                                     |
| `REQUIRE_AUTHENTICATION`      | `false`              | Enable JWT auth for the API                                                                    |
| `COGNEE_SKIP_CONNECTION_TEST` | `false`              | Skip LLM/embedding connectivity checks on startup. Accepts `true`, `1`, or `yes`.              |
| `chunk_size`                  | `1500`               | Max tokens per chunk during cognify (see [Chunkers](/core-concepts/further-concepts/chunkers)) |
| `chunk_overlap`               | `10`                 | Overlap between chunks in words (only affects `LangchainChunker`)                              |

See the full list of options in [Setup Configuration](/setup-configuration/overview).

## Common Setups

<AccordionGroup>
  <Accordion title="Cognee + PostgreSQL">
    PostgreSQL with pgvector is a good production choice for the relational database.

    Add to your `.env`:

    ```bash theme={null}
    DB_PROVIDER=postgres
    DB_HOST=postgres
    DB_PORT=5432
    DB_USERNAME=cognee
    DB_PASSWORD=cognee
    DB_NAME=cognee_db
    ```

    Start both services:

    ```bash theme={null}
    docker compose --profile postgres up --build
    ```
  </Accordion>

  <Accordion title="Cognee + PostgreSQL + Neo4j">
    For production deployments with a dedicated graph database:

    Add to your `.env`:

    ```bash theme={null}
    # Relational DB
    DB_PROVIDER=postgres
    DB_HOST=postgres
    DB_PORT=5432
    DB_USERNAME=cognee
    DB_PASSWORD=cognee
    DB_NAME=cognee_db

    # Graph DB
    GRAPH_DATABASE_PROVIDER=neo4j
    GRAPH_DATABASE_URL=bolt://neo4j:7687
    GRAPH_DATABASE_NAME=neo4j
    GRAPH_DATABASE_USERNAME=neo4j
    GRAPH_DATABASE_PASSWORD=pleaseletmein
    ```

    Start the stack:

    ```bash theme={null}
    docker compose --profile postgres --profile neo4j up --build
    ```

    Neo4j browser is available at `http://localhost:7474`.
  </Accordion>

  <Accordion title="Cognee + ChromaDB">
    Use ChromaDB as the vector store:

    Add to your `.env`:

    ```bash theme={null}
    VECTOR_DB_PROVIDER=chromadb
    VECTOR_DB_URL=http://chromadb:8000
    VECTOR_DB_KEY=your_chroma_token
    ```

    Start:

    ```bash theme={null}
    docker compose --profile chromadb up --build
    ```
  </Accordion>

  <Accordion title="Cognee with MCP Server">
    Run the [MCP server](/cognee-mcp/mcp-overview) alongside the API:

    ```bash theme={null}
    docker compose --profile mcp up --build cognee-mcp
    ```

    The MCP server uses SSE transport on port `8000` (separate container). Configure your IDE to point to `http://localhost:8000/sse`.
  </Accordion>
</AccordionGroup>

## Stopping and Cleaning Up

```bash theme={null}
# Stop containers (preserves volumes)
docker compose down

# Stop and remove volumes (deletes all data)
docker compose down --volumes
```

## Additional Information

<AccordionGroup>
  <Accordion title="Adding optional extras to the Docker image">
    The default Docker image includes a fixed set of extras from the repository `Dockerfile`. If you need features behind another optional dependency, add the matching `--extra <name>` flag to both `uv sync` lines in the `Dockerfile`, then rebuild the image.

    For a table of available extras and common combinations, see [Installation](/getting-started/installation#extras-and-common-installation-combinations).
    For a table of supported file types and their loaders, see [Loaders](/core-concepts/further-concepts/loaders#supported-file-extensions).

    Example: adding the `docs` extra

    ```dockerfile theme={null}
    # First uv sync (--no-install-project):
    RUN --mount=type=cache,target=/root/.cache/uv \
        uv sync --extra debug --extra api --extra postgres --extra neo4j \
                 --extra llama-index --extra ollama --extra mistral --extra groq \
                 --extra anthropic --extra chromadb --extra docs \
                 --frozen --no-install-project --no-dev --no-editable

    # Second uv sync (installs the project):
    RUN --mount=type=cache,target=/root/.cache/uv \
        uv sync --extra debug --extra api --extra postgres --extra neo4j \
                 --extra llama-index --extra ollama --extra mistral --extra groq \
                 --extra anthropic --extra chromadb --extra docs \
                 --frozen --no-dev --no-editable
    ```

    This same pattern works for other extras such as `scraping`, `redis`, `tracing`, `monitoring`, or `docling`.

    Rebuild after updating the `Dockerfile`:

    ```bash theme={null}
    docker compose up --build cognee
    ```
  </Accordion>

  <Accordion title="Fixing 'Connection refused' startup errors with PostgreSQL">
    When Cognee starts before PostgreSQL finishes initializing, the first API call triggers LLM/embedding connectivity checks (`setup_and_check_environment`) and may hit the database before it accepts connections, producing `[Errno 111] Connection refused` or `[Errno 99] Cannot assign requested address`.

    **Recommended fix — add a healthcheck and `depends_on` condition to your `docker-compose.yml`:**

    ```yaml theme={null}
    services:
      postgres:
        image: pgvector/pgvector:pg17
        environment:
          POSTGRES_USER: cognee
          POSTGRES_PASSWORD: cognee
          POSTGRES_DB: cognee_db
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -U cognee -d cognee_db"]
          interval: 10s
          timeout: 5s
          retries: 5

      cognee:
        image: cognee/cognee:main
        depends_on:
          postgres:
            condition: service_healthy
        environment:
          DB_PROVIDER: postgres
          DB_HOST: postgres
          DB_PORT: 5432
          DB_USERNAME: cognee
          DB_PASSWORD: cognee
          DB_NAME: cognee_db
    ```

    This delays the `cognee` container until PostgreSQL passes its health check.

    **Alternative fix — bypass the connectivity check:**

    If you cannot modify the compose file (e.g. third-party orchestration), set `COGNEE_SKIP_CONNECTION_TEST=true` to skip the LLM/embedding startup probe entirely. The check is only performed once (on first run), so the trade-off is that misconfigured endpoints are not caught until the first real request.

    ```bash theme={null}
    COGNEE_SKIP_CONNECTION_TEST=true
    ```
  </Accordion>

  <Accordion title="Enabling office documents and advanced PDF loaders">
    To use [UnstructuredLoader](/core-concepts/further-concepts/loaders#external-loaders) for `.docx`, `.pptx`, `.xlsx`, `.epub`, and similar formats, add `--extra docs` as shown above and rebuild the image.

    That same `docs` extra also enables `AdvancedPdfLoader`. For layout-aware or OCR-based PDF extraction, you additionally need `poppler-utils` and `tesseract-ocr` in the **runtime stage** of your `Dockerfile` (the second `FROM python:3.12-slim-bookworm` block):

    ```dockerfile theme={null}
    RUN apt-get update && apt-get install -y \
        libpq5 \
        curl \
        poppler-utils \
        tesseract-ocr \
        && rm -rf /var/lib/apt/lists/*
    ```

    Once rebuilt, the loaders activate automatically for supported file types with no code changes required.
  </Accordion>
</AccordionGroup>

<Card title="Need help?" href="https://discord.gg/m63hxKsp4p" icon="discord">
  Join our community for Docker deployment support.
</Card>
