1
- # First, build the application and install dependencies
2
1
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS builder
2
+ ARG CPU_ONLY=false
3
3
4
4
WORKDIR /app
5
5
6
- # Download models in builder stage
6
+ # Install build dependencies
7
7
RUN apt-get update && \
8
- apt-get install -y libgl1 libglib2.0-0 && \
9
- apt-get clean
8
+ apt-get install -y --no-install-recommends libgl1 libglib2.0-0 && \
9
+ rm -rf /var/lib/apt/lists/*
10
10
11
11
# Copy only dependency files and create a dummy README
12
12
COPY pyproject.toml uv.lock ./
13
13
# Create a dummy README.md file to satisfy package requirements
14
14
RUN echo "# Placeholder README" > README.md
15
15
16
- # Create venv and install project for model downloads
17
- RUN python -m venv /app/.venv && \
18
- . /app/.venv/bin/activate && \
19
- uv pip install -e .
16
+ # Install dependencies but not the project itself
17
+ RUN --mount=type=cache,target=/root/.cache/uv \
18
+ uv sync --frozen --no-install-project
19
+
20
+ # Copy the rest of the project
21
+ COPY . .
20
22
21
- # Set up cache directories and download models
22
- ENV HF_HOME=/app/.cache/huggingface \
23
- TORCH_HOME=/app/.cache/torch
23
+ # Better GPU detection: Check both architecture and if NVIDIA is available
24
+ RUN ARCH=$(uname -m) && \
25
+ if [ "$CPU_ONLY" = "true" ] || [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ] || ! command -v nvidia-smi >/dev/null 2>&1; then \
26
+ USE_GPU=false; \
27
+ else \
28
+ USE_GPU=true; \
29
+ fi && \
30
+ echo "Detected GPU availability: $USE_GPU" && \
31
+ # For PyTorch installation with architecture detection
32
+ uv pip uninstall -y torch torchvision torchaudio || true && \
33
+ if [ "$USE_GPU" = "false" ]; then \
34
+ # For CPU or ARM architectures or no NVIDIA
35
+ echo "Installing PyTorch for CPU" && \
36
+ uv pip install --no-cache-dir torch torchvision --extra-index-url https://download.pytorch.org/whl/cpu; \
37
+ else \
38
+ # For x86_64 with GPU support
39
+ echo "Installing PyTorch with CUDA support" && \
40
+ uv pip install --no-cache-dir torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121; \
41
+ fi
24
42
25
43
# Download models
26
44
RUN . /app/.venv/bin/activate && \
@@ -29,16 +47,29 @@ RUN . /app/.venv/bin/activate && \
29
47
python -c 'import easyocr; reader = easyocr.Reader(["fr", "de", "es", "en", "it", "pt"], gpu=True); print("EasyOCR models downloaded successfully")' && \
30
48
python -c 'from chonkie import SDPMChunker; chunker = SDPMChunker(embedding_model="minishlab/potion-base-8M"); print("Chonkie models downloaded successfully")'
31
49
32
- # Final stage with CUDA support
33
- FROM python:3.12-slim-bookworm AS runtime
50
+ # Download models for the pipeline
51
+ RUN uv run python -c "from docling.pipeline.standard_pdf_pipeline import StandardPdfPipeline; artifacts_path = StandardPdfPipeline.download_models_hf(force=True)"
34
52
35
- ARG CPU_ONLY=false
53
+ # Pre-download EasyOCR models with better GPU detection
54
+ RUN ARCH=$(uname -m) && \
55
+ if [ "$CPU_ONLY" = "true" ] || [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ] || ! command -v nvidia-smi >/dev/null 2>&1; then \
56
+ echo "Downloading EasyOCR models for CPU" && \
57
+ uv run python -c "import easyocr; reader = easyocr.Reader(['fr', 'de', 'es', 'en', 'it', 'pt'], gpu=False); print('EasyOCR CPU models downloaded successfully')" ; \
58
+ else \
59
+ echo "Downloading EasyOCR models with GPU support" && \
60
+ uv run python -c "import easyocr; reader = easyocr.Reader(['fr', 'de', 'es', 'en', 'it', 'pt'], gpu=True); print('EasyOCR GPU models downloaded successfully')" ; \
61
+ fi
62
+
63
+ RUN uv run python -c 'from chonkie import SDPMChunker; chunker = SDPMChunker(embedding_model="minishlab/potion-base-8M"); print("Chonkie models downloaded successfully")'
64
+
65
+ # Production stage
66
+ FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
36
67
WORKDIR /app
37
68
38
69
# Install runtime dependencies
39
70
RUN apt-get update && \
40
- apt-get install -y redis-server libgl1 libglib2.0-0 && \
41
- apt-get clean
71
+ apt-get install -y --no-install-recommends redis-server libgl1 libglib2.0-0 curl && \
72
+ rm -rf /var/lib/apt/lists/*
42
73
43
74
# Copy model cache from builder - this rarely changes
44
75
COPY --from=builder --chown=app:app /app/.cache /app/.cache/
@@ -57,31 +88,24 @@ COPY --chown=app:app main.py ./
57
88
ENV PYTHONPATH=/app \
58
89
HF_HOME=/app/.cache/huggingface \
59
90
TORCH_HOME=/app/.cache/torch \
60
- OMP_NUM_THREADS=4
91
+ PYTHONPATH=/app \
92
+ OMP_NUM_THREADS=4 \
93
+ UV_COMPILE_BYTECODE=1
61
94
62
- # Create app user
63
- RUN useradd -m app && \
64
- chown -R app:app /app /tmp && \
65
- python -m venv /app/.venv && \
66
- chown -R app:app /app/.venv
95
+ # Create a non-root user
96
+ RUN useradd --create-home app && \
97
+ mkdir -p /app && \
98
+ chown -R app:app /app /tmp
67
99
68
- USER app
100
+ # Copy the virtual environment from the builder stage
101
+ COPY --from=builder --chown=app:app /app/.venv /app/.venv
102
+ ENV PATH="/app/.venv/bin:$PATH"
69
103
70
- # Install dependencies and project
71
- RUN . /app/.venv/bin/activate && \
72
- cd /app && \
73
- pip install -e .
104
+ # Copy necessary files for the application
105
+ COPY --chown=app:app . .
74
106
75
- # Install PyTorch with CUDA support
76
- RUN . /app/.venv/bin/activate && \
77
- if [ "$CPU_ONLY" = "true" ]; then \
78
- pip install --no-cache-dir torch torchvision --extra-index-url https://download.pytorch.org/whl/cpu; \
79
- else \
80
- pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121; \
81
- fi
82
-
83
- ENV PATH="/app/.venv/bin:$PATH"
107
+ # Switch to non-root user
108
+ USER app
84
109
85
110
EXPOSE 8080
86
-
87
- CMD ["python" , "-m" , "uvicorn" , "--port" , "8080" , "--host" , "0.0.0.0" , "main:app" ]
111
+ CMD ["uvicorn" , "main:app" , "--port" , "8080" , "--host" , "0.0.0.0" ]
0 commit comments