
Containerizing Your Graph Stack: Docker for RAG
Package your intelligence for the cloud. Learn how to build a production-grade Docker Compose setup that integrates Neo4j, your Python API, and vector stores into a single deployment unit.
Containerizing Your Graph Stack: Docker for RAG
In development, we ran Neo4j using a simple docker run command. In production, we need something more robust. A professional Graph RAG system has multiple moving parts: the Graph DB, the Vector Index, the FastAPI/Python Orchestrator, and a Message Queue (for asynchronous ingestion). To manage this "Orchestra," we use Docker Compose.
In this lesson, we will build a Production Dockerfile for our RAG agent and a docker-compose.yml file that links all our services together. We will learn how to handle Persistence (so your graph data doesn't disappear when the container restarts) and how to configure Health Checks to ensure the database is ready before the AI starts making queries.
1. The Multi-Service Architecture
For Graph RAG, we typically deploy:
- neo4j: The graph engine + GDS plugin.
- rag-api: Your Python code (LangChain/LangGraph).
- redis: For caching frequent graph results.
graph TD
User((User)) -->|HTTP| API[Graph RAG API]
API -->|Bolt| DB[(Neo4j DB)]
API -->|TCP| Redis[(Redis Cache)]
DB -->|Persistence| Vol[/Local Volume/]
style DB fill:#4285F4,color:#fff
style Redis fill:#f44336,color:#fff
2. The Python RAG Dockerfile
We need to package our Python code with all the dependencies from Module 10.
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy source code
COPY . .
# Environment variables (Defaults)
ENV PORT=8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
3. The Orchestration (Docker Compose)
The "Master Blueprint" for your local or server environment.
version: '3.8'
services:
neo4j:
image: neo4j:enterprise # Or community
ports:
- "7474:7474"
- "7687:7687"
volumes:
- ./data:/data
environment:
- NEO4J_PLUGINS=["graph-data-science", "apoc"]
- NEO4J_AUTH=neo4j/password123
rag-api:
build: .
ports:
- "8000:8000"
depends_on:
neo4j:
condition: service_healthy
env_file: .env
4. Why Persistence Matters (Volumes)
Container storage is Ephemeral. If the machine crashes, your 1-million node graph is gone.
- The Solution: Always map the
/datadirectory of your Neo4j container to a Local Volume on the host machine. This ensures that the graph "Memory" survives even if the "Body" (container) is replaced.
5. Summary and Exercises
Docker ensures that "It works on my machine" means "It works in the cloud."
- Dockerfiles standardize the Python runtime.
- Docker Compose manages the connectivity between the API and the Graph.
- Volumes provide the long-term memory for your knowledge base.
- Health Checks prevent the API from crashing while waiting for the DB to boot up.
Exercises
- Architecture Design: If you add a "Web Scraper" to your system, should it be inside the
rag-apicontainer or a separate service? Why? - Environment Sync: Why is it dangerous to include your
.envfile inside the Docker image? What should you use instead? (Hint:env_filein Compose). - Downtime Drill: Run
docker-compose down. Now rundocker-compose up. Did your data survive? If you used volumes, the answer is YES.
In the next lesson, we will move to the big clouds: Deploying to AWS, GCP, and Azure.