-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
99 lines (81 loc) · 5.14 KB
/
Copy pathDockerfile
File metadata and controls
99 lines (81 loc) · 5.14 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
# ─────────────────────────────────────────────────────────────────────────────
# ERE Prototype — Multi-stage Docker Build
# ─────────────────────────────────────────────────────────────────────────────
# This Dockerfile produces a lean production image with only runtime
# dependencies installed. It uses a two-stage build:
#
# Stage 1 (builder): Installs Poetry, resolves dependencies, and creates
# an in-project virtualenv with production packages only.
#
# Stage 2 (runtime): Copies the pre-built virtualenv and application code
# into a minimal Python image. Runs as non-root user.
#
# Build context: the ere-prototype-template directory.
#
# Usage:
# docker build -t ere-prototype .
# docker run --rm ere-prototype
# docker run --rm -v ./config:/app/config:ro ere-prototype \
# --config /app/config/ere_config_docker.yaml
#
# The image expects a YAML config file at /app/config/ere_config.yaml
# (or override via CMD arguments). Mount a custom config to change behaviour
# without rebuilding the image.
# ─────────────────────────────────────────────────────────────────────────────
# ─── Stage 1: Builder ────────────────────────────────────────────────────────
# Purpose: Install Poetry, resolve dependencies, produce a portable virtualenv.
# This stage is discarded in the final image (only the .venv is copied out).
FROM python:3.12-slim AS builder
WORKDIR /build
# Install Poetry (any 2.x version). We only need it for dependency resolution.
RUN pip install --no-cache-dir "poetry>=2.0,<3.0"
# Tell Poetry to create the virtualenv inside the project directory (.venv/)
# so we can COPY it to the runtime stage as a self-contained artifact.
ENV POETRY_VIRTUALENVS_IN_PROJECT=true
ENV POETRY_VIRTUALENVS_CREATE=true
# Copy only dependency-related files first. This layer is cached as long as
# pyproject.toml and poetry.lock don't change, making rebuilds fast.
COPY pyproject.toml poetry.lock ./
# Install production dependencies only (no dev tools like pytest, ruff, etc.).
# Include the optional storage drivers needed by the configured backends.
# --no-root: Don't install the project itself (we copy source separately).
# --no-interaction: Non-interactive mode for CI/CD.
RUN poetry install --only=main --no-root --no-interaction --no-ansi --extras all-storage
# ─── Stage 2: Runtime ────────────────────────────────────────────────────────
# Purpose: Minimal image with only the application and its runtime dependencies.
# No build tools, no Poetry, no dev dependencies.
FROM python:3.12-slim AS runtime
# Image metadata (OCI labels)
LABEL maintainer="ERE Developer <dev@example.com>"
LABEL description="Entity Resolution Engine (ERE) Prototype — ERS–ERE contract implementation"
LABEL version="0.1.0"
LABEL org.opencontainers.image.source="https://github.com/your-org/ere-prototype"
# Create a dedicated non-root user for security.
# The ERE service does not need root privileges.
RUN groupadd -r ere && useradd -r -g ere -d /app -s /sbin/nologin ere
WORKDIR /app
# Copy the pre-built virtualenv from the builder stage.
# This contains all production Python packages (pydantic, pyyaml, redis, etc.).
COPY --from=builder /build/.venv /app/.venv
# Add the virtualenv's bin directory to PATH so `python` resolves to the venv.
ENV PATH="/app/.venv/bin:$PATH"
# Copy application source code (the ere/ package).
COPY ere/ ./ere/
# Copy configuration files. These can be overridden at runtime via volume mounts.
COPY config/ ./config/
# Set file ownership to the non-root user.
RUN chown -R ere:ere /app
# Switch to non-root user for all subsequent commands and runtime.
USER ere
# ─── Runtime Environment Variables ───────────────────────────────────────────
# ERE_CONFIG: Path to the YAML configuration file (can be overridden).
ENV ERE_CONFIG=/app/config/ere_config.yaml
# PYTHONUNBUFFERED: Ensure print/log output appears immediately in docker logs.
ENV PYTHONUNBUFFERED=1
# PYTHONDONTWRITEBYTECODE: Don't create .pyc files (unnecessary in containers).
ENV PYTHONDONTWRITEBYTECODE=1
# ─── Entry Point ─────────────────────────────────────────────────────────────
# The service starts the consumer loop via `python -m ere.main`.
# The config path is resolved from ERE_CONFIG or the default in-memory config.
ENTRYPOINT ["python", "-m", "ere.main"]
CMD []