Skip to content

Commit b093c27

Browse files
committed
chore: optimize docker build
1 parent 444a5e0 commit b093c27

File tree

2 files changed

+36
-53
lines changed

2 files changed

+36
-53
lines changed

Dockerfile

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1+
# syntax=docker/dockerfile:1.7-labs
12
# =======================
23
# Stage 1 - Builder
34
# =======================
45
FROM python:3.12-slim AS builder
56

67
ARG ENABLE_CUDA=false
7-
8-
WORKDIR /app
9-
108
ENV PYTHONDONTWRITEBYTECODE=1 \
119
PYTHONUNBUFFERED=1 \
1210
PIP_NO_CACHE_DIR=1
1311

14-
# System dependencies for building wheels
12+
WORKDIR /app
13+
14+
# Install system dependencies required for building wheels
1515
RUN apt-get update && apt-get install -y --no-install-recommends \
1616
build-essential \
1717
curl \
@@ -21,79 +21,69 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
2121
# Install Poetry
2222
RUN pip install --no-cache-dir poetry==2.2.1
2323

24-
# Copy dependency files
24+
# Copy only the dependency descriptors first (cache friendly)
2525
COPY pyproject.toml poetry.lock* /app/
2626

2727
# Configure Poetry
2828
RUN poetry config virtualenvs.create false
2929

30-
# Install dependencies based on CUDA flag
31-
RUN --mount=type=cache,id=poetry-cache,target=/root/.cache/pypoetry \
32-
--mount=type=cache,id=pip-cache,target=/root/.cache/pip \
30+
# Install packages (use BuildKit cache mounts so subsequent builds are fast)
31+
# This layer will be reused as long as pyproject/poetry.lock don't change.
32+
RUN --mount=type=cache,target=/root/.cache/pypoetry \
33+
--mount=type=cache,target=/root/.cache/pip \
3334
if [ "$ENABLE_CUDA" = "true" ]; then \
3435
echo "Installing with CUDA support..."; \
3536
poetry install --without dev --no-interaction --no-ansi --no-root; \
3637
else \
3738
echo "Installing CPU-only packages..."; \
38-
poetry install --without dev --no-interaction --no-ansi --no-root && \
39-
pip uninstall -y torch torchvision && \
39+
# install declared dependencies
40+
poetry install --without dev --no-interaction --no-ansi --no-root; \
41+
# replace torch with CPU wheel (if on amd64), keep torch separate to avoid invalidation
42+
pip uninstall -y torch torchvision || true; \
4043
if [ "$TARGETARCH" = "amd64" ]; then \
4144
pip install --no-cache-dir \
42-
torch==2.7.1+cpu \
43-
torchvision==0.22.1+cpu \
44-
--index-url https://download.pytorch.org/whl/cpu; \
45+
torch==2.7.1+cpu \
46+
torchvision==0.22.1+cpu \
47+
--index-url https://download.pytorch.org/whl/cpu; \
4548
else \
4649
pip install --no-cache-dir torch torchvision; \
4750
fi \
4851
fi
4952

50-
# Clean up unnecessary files
51-
RUN find /usr/local/lib/python3.12 -type d -name "tests" -exec rm -rf {} + 2>/dev/null || true && \
52-
find /usr/local/lib/python3.12 -type d -name "test" -exec rm -rf {} + 2>/dev/null || true && \
53-
find /usr/local/lib/python3.12 -type f -name "*.pyc" -delete && \
54-
find /usr/local/lib/python3.12 -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
53+
# Remove tests/caches from site-packages to reduce image size
54+
RUN find /usr/local/lib/python3.12 -type d \( -name "tests" -o -name "test" -o -name "__pycache__" \) -exec rm -rf {} + 2>/dev/null || true \
55+
&& find /usr/local/lib/python3.12 -type f -name "*.pyc" -delete
5556

5657
# =======================
5758
# Stage 2 - Runtime
5859
# =======================
5960
FROM python:3.12-slim AS runtime
6061

6162
ARG ENABLE_CUDA=false
62-
63-
WORKDIR /app
64-
6563
ENV PYTHONDONTWRITEBYTECODE=1 \
6664
PYTHONUNBUFFERED=1 \
6765
PYTHONPATH=/app \
6866
PORT=8080 \
6967
ENABLE_CUDA=${ENABLE_CUDA}
7068

71-
# Install only runtime dependencies
69+
WORKDIR /app
70+
71+
# Install small runtime system libs
7272
RUN apt-get update && apt-get install -y --no-install-recommends \
7373
curl \
7474
libgomp1 \
7575
&& rm -rf /var/lib/apt/lists/*
7676

77-
# Copy only site-packages (not entire lib)
77+
# Copy installed site-packages and runtime binaries from builder
7878
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
7979
COPY --from=builder /usr/local/bin/uvicorn /usr/local/bin/uvicorn
8080
COPY --from=builder /usr/local/bin/gunicorn /usr/local/bin/gunicorn
8181

82-
# Add non-root user
83-
# RUN groupadd -r appuser && useradd -r -g appuser appuser
84-
85-
# Copy local spaCy model
86-
# COPY --chown=appuser:appuser spacy_models /app/spacy_models
87-
88-
# Copy application code
89-
# COPY --chown=appuser:appuser app /app/app
82+
# Copy application source last so code changes do not bust earlier caches
83+
COPY . /app
9084

9185
# Create runtime directories
9286
RUN mkdir -p /app/data/uploads /app/data/temp /app/logs
93-
# RUN mkdir -p /app/data/uploads /app/data/temp /app/logs \
94-
# && chown -R appuser:appuser /app
95-
96-
# USER appuser
9787

9888
EXPOSE 8080
9989

docker-compose.yml

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,51 @@
1+
version: "3.9"
2+
13
services:
24
braindrive-document-ai:
35
build:
46
context: .
57
dockerfile: Dockerfile
68
args:
79
ENABLE_CUDA: ${ENABLE_CUDA:-false}
8-
# cache_from:
9-
# - type=local,src=/tmp/docker-cache
10-
# cache_to:
11-
# - type=local,dest=/tmp/docker-cache,mode=max
10+
# BuildKit cache hints (requires BuildKit to be enabled)
11+
cache_from:
12+
- type=local,src=.buildx-cache
13+
cache_to:
14+
- type=local,dest=.buildx-cache,mode=max
1215
ports:
1316
- "8080:8080"
1417

1518
environment:
16-
# Authentication
1719
- DISABLE_AUTH=${DISABLE_AUTH:-true}
1820
- AUTH_METHOD=${AUTH_METHOD:-api_key}
1921
- AUTH_API_KEY=${AUTH_API_KEY:-}
2022
- JWT_SECRET=${JWT_SECRET:-}
2123
- JWT_ALGORITHM=${JWT_ALGORITHM:-HS256}
2224
- JWT_EXPIRE_MINUTES=${JWT_EXPIRE_MINUTES:-60}
23-
24-
# Document processing
2525
- SPACY_MODEL=${SPACY_MODEL:-/app/spacy_models/en_core_web_sm/en_core_web_sm-3.8.0}
2626
- DEFAULT_CHUNKING_STRATEGY=${DEFAULT_CHUNKING_STRATEGY:-hierarchical}
2727
- DEFAULT_CHUNK_SIZE=${DEFAULT_CHUNK_SIZE:-1000}
2828
- DEFAULT_CHUNK_OVERLAP=${DEFAULT_CHUNK_OVERLAP:-200}
2929
- MIN_CHUNK_SIZE=${MIN_CHUNK_SIZE:-100}
3030
- MAX_CHUNK_SIZE=${MAX_CHUNK_SIZE:-2000}
31-
32-
# CUDA toggle (default CPU, enable with ENABLE_CUDA=true)
3331
- ENABLE_CUDA=${ENABLE_CUDA:-false}
34-
35-
# Logging
3632
- LOG_FORMAT=${LOG_FORMAT:-console}
3733
- LOG_FILE=${LOG_FILE:-/app/logs/app.log}
38-
34+
3935
volumes:
4036
- ../../persistent/document_processing/data:/app/data
4137
- ../../persistent/document_processing/logs:/app/logs
4238
- .:/app # Mount source code for development
43-
39+
4440
healthcheck:
4541
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
4642
interval: 30s
4743
timeout: 10s
4844
retries: 3
4945
start_period: 40s
50-
46+
5147
restart: unless-stopped
52-
53-
# Development overrides
54-
# command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080", "--reload"]
55-
48+
5649
networks:
5750
- braindrive-network
5851

0 commit comments

Comments
 (0)