-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDockerfile.min
More file actions
106 lines (91 loc) · 4.36 KB
/
Copy pathDockerfile.min
File metadata and controls
106 lines (91 loc) · 4.36 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
# Dockerfile.min - Minimal CPU image with no preloaded models
#
# FAST BUILD (no model downloads - ~30 seconds):
# Linux/Mac: docker build -f Dockerfile.min -t scottgal/mostlylucid-nmt:cpu-min --build-arg VERSION=$(date -u +"%Y%m%d.%H%M%S") .
# Windows: docker build -f Dockerfile.min -t scottgal/mostlylucid-nmt:cpu-min .
#
# FASTEST DEVELOPMENT WORKFLOW (code updates only):
# 1. Build once: docker build -f Dockerfile.min -t dev .
# 2. Code-only rebuild: ~3 seconds (just copies updated .py files)
# 3. Zero-rebuild option: Mount source code directly
#
# Linux/Mac:
# docker run -p 8000:8000 -v $(pwd)/src:/app/src -v $(pwd)/app.py:/app/app.py -v ./model-cache:/models dev
#
# Windows:
# docker run -p 8000:8000 -v ${PWD}/src:/app/src -v ${PWD}/app.py:/app/app.py -v ${PWD}/model-cache:/models dev
#
# Run with volume mapping for model cache:
# Linux/Mac: docker run -p 8000:8000 -v /path/to/model-cache:/models scottgal/mostlylucid-nmt:cpu-min
# Windows: docker run -p 8000:8000 -v ${PWD}/model-cache:/models scottgal/mostlylucid-nmt:cpu-min
#
# LAYER CACHING: Optimized for fast rebuilds
# 1. Base image (cached)
# 2. Python dependencies (cached unless requirements.txt changes)
# 3. Source code (rebuilds on .py changes - FAST, ~3 seconds!)
#
FROM python:3.12-slim
# Build arguments for versioning
ARG VERSION=dev
ARG BUILD_DATE
ARG VCS_REF
# OCI labels for metadata
LABEL org.opencontainers.image.title="mostlylucid-nmt" \
org.opencontainers.image.description="FastAPI neural machine translation service - CPU minimal, no preloaded models" \
org.opencontainers.image.version="${VERSION}" \
org.opencontainers.image.created="${BUILD_DATE}" \
org.opencontainers.image.source="https://github.com/scottgal/mostlylucid-nmt" \
org.opencontainers.image.revision="${VCS_REF}" \
org.opencontainers.image.vendor="scottgal" \
org.opencontainers.image.licenses="MIT" \
org.opencontainers.image.documentation="https://github.com/scottgal/mostlylucid-nmt/blob/main/README.md" \
variant="cpu-min"
# Prevent interactive prompts and reduce image size
ENV DEBIAN_FRONTEND=noninteractive \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
# Point all caches to the mounted volume to avoid baking anything into the image
HF_HOME=/models \
HF_DATASETS_CACHE=/models \
TORCH_HOME=/models \
# Performance defaults optimized for CPU (fast as possible)
WEB_CONCURRENCY=4 \
MAX_WORKERS_BACKEND=4 \
MAX_INFLIGHT_TRANSLATIONS=4 \
EASYNMT_BATCH_SIZE=16 \
MAX_CACHED_MODELS=5 \
ENABLE_QUEUE=1 \
MAX_QUEUE_SIZE=1000 \
# Fast shutdown (5s graceful timeout instead of 20s)
GRACEFUL_TIMEOUT=5
WORKDIR /app
# Ensure Python can import from /app (for "from src.app import app")
ENV PYTHONPATH=/app
# Install only what is necessary; python:3.12-slim already has SSL runtime
# Keep image minimal by avoiding build toolchains
# (If a dependency needs compilation, switch to the full CPU image)
# Install dependencies - uses CTranslate2 instead of PyTorch (~20MB vs ~200MB)
COPY requirements-prod-cpu.txt .
# --no-cache-dir: Reduces image size by not storing pip's download cache (~100MB saved)
# Docker layer caching still works! When requirements changes, this layer rebuilds
RUN pip install --no-cache-dir -r requirements-prod-cpu.txt
# Copy source code (small)
COPY src/ ./src/
COPY public/ ./public/
COPY app.py .
# CRITICAL: Remove any UTF-8 BOM characters that may have been introduced during COPY
# BOMs (ef bb bf) cause "ModuleNotFoundError: No module named 'src.app'" under Gunicorn
# This defensive fix ensures BOMs are stripped from all Python files in the final image
RUN find /app -name "*.py" -type f -exec sed -i '1s/^\xEF\xBB\xBF//' {} \; || true
# Create directory for model cache (mounted as volume at runtime)
RUN mkdir -p /models
# Set default model cache directory
ENV MODEL_CACHE_DIR=/models
# Ensure no preload happens by default
ENV PRELOAD_MODELS=""
EXPOSE 8000
# Ensure fast, graceful shutdown: send SIGTERM and let Gunicorn handle it
STOPSIGNAL SIGTERM
# Use exec so Gunicorn becomes PID 1 and receives signals directly; add graceful timeout
CMD ["/bin/sh", "-c", "exec gunicorn -k uvicorn.workers.UvicornWorker -w ${WEB_CONCURRENCY:-1} -b 0.0.0.0:8000 --timeout ${TIMEOUT:-0} --graceful-timeout ${GRACEFUL_TIMEOUT:-30} --keep-alive ${KEEP_ALIVE:-5} app:app"]