File size: 5,185 Bytes
f5754e0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
FROM ubuntu:22.04

# Avoid tzdata interactive prompts
ENV DEBIAN_FRONTEND=noninteractive

# Install system dependencies and Python 3.12
RUN apt-get update && apt-get install -y software-properties-common \
    && add-apt-repository ppa:deadsnakes/ppa \
    && apt-get update && apt-get install -y \
    python3.12 \
    python3.12-venv \
    python3.12-dev \
    python3-pip \
    curl \
    wget \
    git \
    redis-server \
    openjdk-17-jdk \
    libmagic1 \
    && rm -rf /var/lib/apt/lists/*

# Install Node.js for frontend build
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
    && apt-get install -y nodejs

# Create app directory
WORKDIR /app

# Download and extract Neo4j and GDS plugin
RUN wget -q https://neo4j.com/artifact.php?name=neo4j-community-5.18.0-unix.tar.gz -O neo4j.tar.gz \
    && tar -xf neo4j.tar.gz \
    && mv neo4j-community-5.18.0 neo4j \
    && rm neo4j.tar.gz \
    && wget -q https://github.com/neo4j/graph-data-science/releases/download/2.6.4/neo4j-graph-data-science-2.6.4.jar -O neo4j/plugins/neo4j-graph-data-science.jar

# Configure Neo4j for demo mode (disable auth, limit memory, enable GDS)
RUN echo "dbms.security.auth_enabled=false" >> neo4j/conf/neo4j.conf \
    && echo "server.memory.heap.initial_size=512m" >> neo4j/conf/neo4j.conf \
    && echo "server.memory.heap.max_size=1G" >> neo4j/conf/neo4j.conf \
    && echo "server.memory.pagecache.size=1G" >> neo4j/conf/neo4j.conf \
    && echo "dbms.security.procedures.unrestricted=gds.*" >> neo4j/conf/neo4j.conf

# Copy project files
COPY . .

# Build frontend
WORKDIR /app/frontend-react
RUN npm install
RUN npm run build

# Setup Python backend
WORKDIR /app
RUN python3.12 -m venv .venv
ENV PATH="/app/.venv/bin:$PATH"
RUN pip install --upgrade pip
RUN pip install -e .

# Create start script
RUN echo '#!/bin/bash\n\
\n\
# Start Redis\n\
redis-server --daemonize yes\n\
\n\
# Start Neo4j in background\n\
/app/neo4j/bin/neo4j start\n\
\n\
# Wait for Neo4j to be ready\n\
echo "Waiting for Neo4j to start..."\n\
while ! curl -s http://localhost:7474 > /dev/null; do\n\
    sleep 2\n\
done\n\
echo "Neo4j HTTP is up! Waiting for Bolt (7687)..."\n\
while ! (echo > /dev/tcp/localhost/7687) >/dev/null 2>&1; do\n\
    sleep 2\n\
done\n\
echo "Neo4j is up!"\n\
\n\
# Set environment variables for Demo Mode\n\
export NEO4J_URI=bolt://localhost:7687\n\
export NEO4J_USER=neo4j\n\
export NEO4J_PASSWORD=dummy\n\
export REDIS_HOST=localhost\n\
export REDIS_PORT=6379\n\
export REDIS_DB=0\n\
export DEMO_MODE=true\n\
export ENVIRONMENT=production\n\
export SECRET_KEY=demo-secret-key-1234567890\n\
\n\
if [ -z "$GOOGLE_API_KEY" ]; then\n\
    export DEFAULT_LLM_PROVIDER=mock\n\
    export EMBEDDING_PROVIDER=mock\n\
    export DEMO_MODE=true\n\
    echo "[WARNING] GOOGLE_API_KEY is not set. Running in DEMO_MODE with mock LLM provider."\n\
else\n\
    export DEFAULT_LLM_PROVIDER=gemini\n\
    export EMBEDDING_PROVIDER=gemini\n\
fi\n\
\n\
# Create default admin user in Neo4j\n\
python -c "\n\
import asyncio\n\
from src.graph_rag_service.core.neo4j_store import Neo4jStore\n\
from src.graph_rag_service.api.auth import get_password_hash\n\
\n\
async def main():\n\
    store = Neo4jStore()\n\
    await store.connect()\n\
    try:\n\
        await store.create_user({\n\
            '\''username'\'': '\''admin'\'',\n\
            '\''hashed_password'\'': get_password_hash('\''admin'\''),\n\
            '\''email'\'': '\''admin@example.com'\'',\n\
            '\''full_name'\'': '\''Demo Admin'\'',\n\
            '\''disabled'\'': False,\n\
            '\''scopes'\'': ['\''read'\'', '\''write'\'', '\''admin'\''],\n\
            '\''tenant_id'\'': '\''demo_tenant'\'',\n\
        })\n\
        print('\''Admin user created in Neo4j'\'')\n\
        \n\
        # Check GDS\n\
        gds_res = await store.execute_query('\''RETURN gds.version() as version'\'')\n\
        print('\''GDS Plugin Version:'\'', gds_res[0]["version"] if gds_res else '\''NOT FOUND'\'')\n\
    except Exception as e:\n\
        print(f'\''Admin user creation note: {e}'\'')\n\
        raise e\n\
    await store.disconnect()\n\
\n\
asyncio.run(main())\n\
"\n\
if [ $? -ne 0 ]; then\n\
    echo "Admin seed failed, retrying in 5 seconds..."\n\
    sleep 5\n\
    python -c "\n\
import asyncio\n\
from src.graph_rag_service.core.neo4j_store import Neo4jStore\n\
from src.graph_rag_service.api.auth import get_password_hash\n\
\n\
async def main():\n\
    store = Neo4jStore()\n\
    await store.connect()\n\
    try:\n\
        await store.create_user({'username': 'admin', 'hashed_password': get_password_hash('admin'), 'scopes': ['read', 'write', 'admin'], 'tenant_id': 'demo_tenant'})\n\
    except Exception as e: pass\n\
    await store.disconnect()\n\
asyncio.run(main())\n\
    "\n\
fi\n\
\n\
# Start Celery worker in the background\n\
celery -A src.graph_rag_service.workers.celery_worker worker --loglevel=info --concurrency=1 --pool=threads &\n\
\n\
# Start FastAPI and serve static files (frontend)\n\
uvicorn src.graph_rag_service.api.server:app --host 0.0.0.0 --port 7860\n\
' > start.sh && chmod +x start.sh

# HF Spaces requires serving on 7860
EXPOSE 7860

CMD ["./start.sh"]