# ========================= # Stage 1 — Builder # ========================= FROM python:3.13-slim AS builder WORKDIR /app # Install system deps RUN apt-get update && apt-get install -y --no-install-recommends \ gcc curl wget \ && rm -rf /var/lib/apt/lists/* # Install uv (fast dependency manager) RUN pip install --no-cache-dir uv # Install Dapr CLI RUN curl -fsSL https://raw.githubusercontent.com/dapr/cli/master/install/install.sh | /bin/bash # Init dapr runtime (slim = no Redis/Zipkin containers) RUN dapr init --slim # Copy dependency files first (better caching) COPY pyproject.toml uv.lock* ./ # Create venv + install deps ENV UV_SYSTEM_PYTHON=0 RUN uv venv /app/.venv && \ . /app/.venv/bin/activate && \ uv pip install -r pyproject.toml # Copy app code COPY . . # ========================= # Stage 2 — Runner # ========================= FROM python:3.13-slim AS runner # Create non-root user RUN groupadd --system --gid 1001 appgroup && \ useradd --system --uid 1001 --gid appgroup --create-home appuser WORKDIR /app # Copy virtual environment COPY --from=builder /app/.venv /app/.venv # Copy app source COPY --from=builder /app/src /app/src # Copy Dapr binaries + config COPY --from=builder /usr/local/bin/dapr /usr/local/bin/dapr COPY --from=builder /root/.dapr /home/appuser/.dapr # Permissions RUN chown -R appuser:appgroup /app /home/appuser/.dapr USER appuser # Environment ENV PYTHONUNBUFFERED=1 ENV PYTHONDONTWRITEBYTECODE=1 ENV PORT=7860 # Expose ports EXPOSE 7860 3500 # Healthcheck (matches FastAPI port) HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:7860/health || exit 1 # ========================= # Start Dapr + FastAPI # ========================= CMD ["/bin/sh", "-c", "\ /home/appuser/.dapr/bin/daprd \ --app-id taskflow \ --app-port 7860 \ --dapr-http-port 3500 \ --resources-path /home/appuser/.dapr/components \ & \ /app/.venv/bin/uvicorn src.main:app --host 0.0.0.0 --port 7860 \ "]