fix: run cognee in Docker [COG-1961] (#775)

<!-- .github/pull_request_template.md -->

## Description
Resolve issue with .venv being broken when using docker compose with
Cognee

## DCO Affirmation
I affirm that all code in every commit of this pull request conforms to
the terms of the Topoteretes Developer Certificate of Origin.

---------

Co-authored-by: Boris Arzentar <borisarzentar@gmail.com>
This commit is contained in:
Igor Ilic 2025-04-23 21:11:16 +02:00 committed by GitHub
parent 49f2e51c17
commit 98a1b79293
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 134 additions and 14 deletions

View file

@ -36,9 +36,10 @@ jobs:
id: build
uses: docker/build-push-action@v5
with:
context: cognee-mcp
context: .
platforms: linux/amd64,linux/arm64
push: true
file: cognee-mcp/Dockerfile
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=cognee/cognee-mcp:buildcache

View file

@ -25,7 +25,7 @@ ENV DEBUG=${DEBUG}
ENV PIP_NO_CACHE_DIR=true
ENV PATH="${PATH}:/root/.poetry/bin"
RUN apt-get update && apt-get install
RUN apt-get update
RUN apt-get install -y \
gcc \

View file

@ -0,0 +1,28 @@
"""Add default user
Revision ID: 482cd6517ce4
Revises: 8057ae7329c2
Create Date: 2024-10-16 22:17:18.634638
"""
from typing import Sequence, Union
from sqlalchemy.util import await_only
from cognee.modules.users.methods import create_default_user, delete_user
# revision identifiers, used by Alembic.
revision: str = "482cd6517ce4"
down_revision: Union[str, None] = "8057ae7329c2"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = "8057ae7329c2"
def upgrade() -> None:
await_only(create_default_user())
def downgrade() -> None:
await_only(delete_user("default_user@example.com"))

View file

@ -0,0 +1,27 @@
"""Initial migration
Revision ID: 8057ae7329c2
Revises:
Create Date: 2024-10-02 12:55:20.989372
"""
from typing import Sequence, Union
from sqlalchemy.util import await_only
from cognee.infrastructure.databases.relational import get_relational_engine
# revision identifiers, used by Alembic.
revision: str = "8057ae7329c2"
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
db_engine = get_relational_engine()
await_only(db_engine.create_database())
def downgrade() -> None:
db_engine = get_relational_engine()
await_only(db_engine.delete_database())

View file

@ -22,7 +22,7 @@ RUN apt-get update && apt-get install -y \
libpq-dev
# Copy pyproject.toml and lockfile first for better caching
COPY pyproject.toml uv.lock ./
COPY ./cognee-mcp/pyproject.toml ./cognee-mcp/uv.lock ./cognee-mcp/entrypoint.sh ./
# Install the project's dependencies using the lockfile and settings
RUN --mount=type=cache,target=/root/.cache/uv \
@ -31,19 +31,25 @@ RUN --mount=type=cache,target=/root/.cache/uv \
# Copy .env file first if it exists (for environment variables)
COPY .env* /app/
# Copy Alembic configuration
COPY alembic.ini /app/alembic.ini
COPY alembic/ /app/alembic
# Then, add the rest of the project source code and install it
# Installing separately from its dependencies allows optimal layer caching
COPY . /app
COPY ./cognee-mcp /app
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev --no-editable
FROM python:3.12-slim-bookworm
WORKDIR /app
COPY --from=uv /root/.local /root/.local
COPY --from=uv /app /app
RUN chmod +x /app/entrypoint.sh
# Place executables in the environment at the front of the path
ENV PATH="/app/.venv/bin:$PATH"
@ -54,4 +60,4 @@ ENV PYTHONPATH=/app
# Use the application name from pyproject.toml for normal operation
# For testing, we'll override this with a direct command
ENTRYPOINT ["cognee"]
ENTRYPOINT ["/app/entrypoint.sh"]

View file

@ -84,3 +84,22 @@ To apply new changes while developing cognee you need to do:
1. `poetry lock` in cognee folder
2. `uv sync --dev --all-extras --reinstall`
3. `mcp dev src/server.py`
### Development
In order to use local cognee build, run in root of the cognee repo:
```bash
poetry build -o ./cognee-mcp/sources
```
After the build process is done, change the cognee library dependency inside the `cognee-mcp/pyproject.toml` from
```toml
cognee[postgres,codegraph,gemini,huggingface]==0.1.38
```
to
```toml
cognee[postgres,codegraph,gemini,huggingface]
```
After that add the following snippet to the same file (`cognee-mcp/pyproject.toml`).
```toml
[tool.uv.sources]
cognee = { path = "sources/cognee-0.1.38-py3-none-any.whl" }
```

41
cognee-mcp/entrypoint.sh Normal file
View file

@ -0,0 +1,41 @@
#!/bin/bash
set -e # Exit on error
echo "Debug mode: $DEBUG"
echo "Environment: $ENVIRONMENT"
# Run Alembic migrations with proper error handling.
# Note on UserAlreadyExists error handling:
# During database migrations, we attempt to create a default user. If this user
# already exists (e.g., from a previous deployment or migration), it's not a
# critical error and shouldn't prevent the application from starting. This is
# different from other migration errors which could indicate database schema
# inconsistencies and should cause the startup to fail. This check allows for
# smooth redeployments and container restarts while maintaining data integrity.
echo "Running database migrations..."
MIGRATION_OUTPUT=$(uv run alembic upgrade head 2>&1) || {
if [[ $MIGRATION_OUTPUT == *"UserAlreadyExists"* ]] || [[ $MIGRATION_OUTPUT == *"User default_user@example.com already exists"* ]]; then
echo "Warning: Default user already exists, continuing startup..."
else
echo "Migration failed with unexpected error:"
echo "$MIGRATION_OUTPUT"
exit 1
fi
}
echo "Starting Cognee MCP Server"
# Add startup delay to ensure DB is ready
sleep 2
# Modified Gunicorn startup with error handling
if [ "$ENVIRONMENT" = "dev" ] || [ "$ENVIRONMENT" = "local" ]; then
if [ "$DEBUG" = "true" ]; then
echo "Waiting for the debugger to attach..."
exec python -m debugpy --wait-for-client --listen 0.0.0.0:5678 -m cognee
else
exec cognee
fi
else
exec cognee
fi

View file

@ -36,11 +36,11 @@ async def list_tools() -> list[types.Tool]:
},
"graph_model_file": {
"type": "string",
"description": "The path to the graph model file",
"description": "The path to the graph model file (Optional)",
},
"graph_model_name": {
"type": "string",
"description": "The name of the graph model",
"description": "The name of the graph model (Optional)",
},
},
"required": ["text"],

View file

@ -7,8 +7,8 @@ services:
context: .
dockerfile: Dockerfile
volumes:
- .:/app
- /app/cognee-frontend/ # Ignore frontend code
- ./cognee:/app/cognee
- .env:/app/.env
environment:
- DEBUG=false # Change to true if debugging
- HOST=0.0.0.0
@ -26,10 +26,8 @@ services:
cpus: "4.0"
memory: 8GB
# NOTE: Frontend is a work in progress and is not intended to be used by users yet.
# If you want to use Cognee with a UI environment you can run the cognee-gui.py script or
# integrate the Cognee MCP Server to Cursor / Claude Desktop / Visual Studio Code ( through Cline/Roo )
# NOTE: Frontend is a work in progress and supports minimum amount of features required to be functional.
# If you want to use Cognee with a UI environment you can integrate the Cognee MCP Server into Cursor / Claude Desktop / Visual Studio Code (through Cline/Roo)
frontend:
container_name: frontend
profiles: