-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathDockerfile
More file actions
131 lines (110 loc) · 4.71 KB
/
Dockerfile
File metadata and controls
131 lines (110 loc) · 4.71 KB
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
# =============================================================================
# Multi-stage Dockerfile for Code Graph Knowledge System
# =============================================================================
#
# OPTIMIZATION STRATEGY:
# 1. Uses uv official image - uv pre-installed, optimized base
# 2. Uses requirements.txt - pre-compiled, no CUDA/GPU dependencies
# 3. BuildKit cache mounts - faster rebuilds with persistent cache
# 4. Multi-stage build - minimal final image
# 5. Layer caching - dependencies rebuild only when requirements.txt changes
# 6. Pre-built frontend - no Node.js/npm/bun in image, only static files
#
# IMAGE SIZE REDUCTION:
# - Base image: python:3.13-slim → uv:python3.13-bookworm-slim (smaller)
# - No build-essential needed (uv handles compilation efficiently)
# - No Node.js/npm/bun needed (frontend pre-built outside Docker)
# - requirements.txt: 373 dependencies, 0 NVIDIA CUDA packages
# - Estimated size: ~1.2GB (from >5GB, -76%)
# - Build time: ~80% faster (BuildKit cache + pre-built frontend)
#
# =============================================================================
# ============================================
# Builder stage
# ============================================
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS builder
# Set environment variables
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
UV_COMPILE_BYTECODE=1 \
UV_LINK_MODE=copy
# Install minimal system dependencies (git for repo cloning, curl for health checks)
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
curl \
&& rm -rf /var/lib/apt/lists/*
# Set work directory
WORKDIR /app
# Copy ONLY requirements.txt first for optimal layer caching
COPY requirements.txt ./
# Install Python dependencies using uv with BuildKit cache mount
# This leverages uv's efficient dependency resolution and caching
RUN --mount=type=cache,target=/root/.cache/uv \
uv pip install --system --no-cache -r requirements.txt
# Copy application source code for local package installation
COPY pyproject.toml README.md ./
COPY src ./src
COPY *.py ./
# Install local package (without dependencies, already installed)
RUN --mount=type=cache,target=/root/.cache/uv \
uv pip install --system --no-cache --no-deps -e .
# ============================================
# Final stage
# ============================================
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim
# Set environment variables
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PATH="/app:${PATH}"
# Install runtime dependencies (minimal)
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
curl \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN useradd -m -u 1000 appuser && \
mkdir -p /app /data /tmp/repos && \
chown -R appuser:appuser /app /data /tmp/repos
# Set work directory
WORKDIR /app
# Copy Python packages from builder (site-packages only)
COPY --from=builder /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages
# Copy only package entry point scripts (not build tools like uv, pip-compile, etc.)
# Note: python binaries already exist in base image, no need to copy
COPY --from=builder /usr/local/bin/uvicorn /usr/local/bin/
# Copy application code
COPY --chown=appuser:appuser . .
# Copy pre-built frontend (if exists)
# Run ./scripts/build-frontend.sh before docker build to generate frontend/dist
# If frontend/dist doesn't exist, the app will run as API-only (no web UI)
RUN if [ -d frontend/dist ]; then \
mkdir -p static && \
cp -r frontend/dist/* static/ && \
echo "✅ Frontend copied to static/"; \
else \
echo "⚠️ No frontend/dist found - running as API-only"; \
echo " Run ./scripts/build-frontend.sh to build frontend"; \
fi
# Switch to non-root user
USER appuser
# Expose ports (Two-Port Architecture)
#
# PORT 8000: MCP SSE Service (PRIMARY)
# - GET /sse - MCP SSE connection endpoint
# - POST /messages/ - MCP message receiving endpoint
# Purpose: Core MCP service for AI clients
#
# PORT 8080: Web UI + REST API (SECONDARY)
# - GET / - Web UI (React SPA for monitoring)
# - * /api/v1/* - REST API endpoints
# - GET /metrics - Prometheus metrics
# Purpose: Status monitoring and programmatic access
#
# Note: stdio mode (start_mcp.py) still available for local development
EXPOSE 8000 8080
# Health check (check both services)
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD curl -f http://localhost:8080/api/v1/health || exit 1
# Default command - starts both MCP and Web services (dual-port mode)
# Alternative: python -m codebase_rag --mcp (MCP only) or --web (Web only)
CMD ["python", "-m", "codebase_rag"]