-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
88 lines (76 loc) · 3.87 KB
/
Copy pathDockerfile
File metadata and controls
88 lines (76 loc) · 3.87 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
# Inference container for the credit risk scoring service.
#
# Build strategy:
# - python:3.11-slim base: minimal OS footprint, no build tools.
# - requirements/serving.txt copied first so the pip install layer is
# cached across application code changes (most builds skip pip install).
# - Application code copied after dependencies.
# - Non-root user (appuser, UID 1000) for security hardening.
# - No training dependencies (torch, xgboost training libs) - serving only.
#
# Expected image size: ~600 MB (onnxruntime ~300 MB + python + app).
# Training image with full torch would be ~5 GB.
#
# Build and push (run from repo root):
# docker build -t credit-risk-inference:$(git rev-parse --short HEAD) .
# docker tag credit-risk-inference:<tag> <account>.dkr.ecr.<region>.amazonaws.com/credit-risk-inference:<tag>
# docker push <account>.dkr.ecr.<region>.amazonaws.com/credit-risk-inference:<tag>
FROM python:3.11-slim AS base
# Install OS dependencies needed by onnxruntime and some Python packages.
# libgomp1: OpenMP runtime required by onnxruntime CPU kernels.
# curl: health check fallback from shell.
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
libgomp1 \
curl \
&& rm -rf /var/lib/apt/lists/*
# Create non-root user. UID 1000 is standard; matches common CI environments.
RUN groupadd --gid 1000 appgroup \
&& useradd --uid 1000 --gid appgroup --shell /bin/bash --create-home appuser
WORKDIR /app
# ---------------------------------------------------------------------------
# Dependency layer (cached unless requirements/serving.txt changes)
# ---------------------------------------------------------------------------
COPY requirements/serving.txt requirements/serving.txt
RUN pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir -r requirements/serving.txt
# ---------------------------------------------------------------------------
# Application code
# ---------------------------------------------------------------------------
# Copy only the modules needed at serving time.
# - src/serving/: inference handler, ONNX runtime wrapper, SageMaker endpoint.
# - src/ingestion/schema-validator.py: Pydantic schemas used by API layer.
# - src/features/: Feast feature definitions (needed by FeatureStore init).
# - src/api/: FastAPI application (Phase 6 - included now for complete image).
# - configs/: base.yaml config file.
COPY src/serving/ src/serving/
COPY src/ingestion/schema-validator.py src/ingestion/schema-validator.py
COPY src/features/ src/features/
COPY configs/base.yaml configs/base.yaml
# Placeholder for the API layer (written in Phase 6).
# This COPY is harmless if src/api/ doesn't exist yet during the Phase 4 build.
COPY src/api/ src/api/
# ---------------------------------------------------------------------------
# Runtime configuration
# ---------------------------------------------------------------------------
# Model artifacts are NOT baked into the image. The EKS init container
# downloads them from S3 at pod startup (see infra/k8s/deployment.yaml).
# This keeps the image small and allows model updates without image rebuilds.
# Switch to non-root user before CMD.
USER appuser
# Expose HTTP and Prometheus metrics ports.
EXPOSE 8000
EXPOSE 9090
# Health check: the container is healthy if /v1/health returns 200.
# --interval 10s matches the Kubernetes liveness probe period.
HEALTHCHECK --interval=10s --timeout=5s --start-period=30s --retries=3 \
CMD curl -f http://localhost:8000/v1/health || exit 1
# Default entry point: uvicorn serving the FastAPI app.
# Worker count of 1 because we use asyncio concurrency, not multiprocessing.
# Gunicorn with uvicorn workers is the production pattern for multi-core CPUs.
CMD ["python", "-m", "uvicorn", "src.api.main:app", \
"--host", "0.0.0.0", \
"--port", "8000", \
"--workers", "1", \
"--log-level", "info", \
"--access-log"]