# Production Dockerfile for the AI Crop Decision Support System.
#
# Build: docker build -t crop-ai-system:latest -f deployment/docker/Dockerfile .
# This single image serves both the API (overriding CMD with gunicorn)
# and the Celery worker (overriding CMD with celery worker) — see
# deployment/docker/docker-compose.yml for how both roles are run from
# one image with different commands.

FROM python:3.12-slim AS base

# System dependencies needed for psycopg2, xgboost, statsmodels compilation
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    libpq-dev \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Install Python deps in a separate layer so code changes don't bust
# the dependency cache on every rebuild.
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Create a non-root user — never run the app as root in production.
RUN useradd --create-home --shell /bin/false cropai

COPY --chown=cropai:cropai app ./app
COPY --chown=cropai:cropai ml_pipeline ./ml_pipeline
COPY --chown=cropai:cropai alembic ./alembic
COPY --chown=cropai:cropai alembic.ini .
COPY --chown=cropai:cropai data/lookup ./data/lookup

# Model artifacts are NOT baked into the image — they are mounted as a
# volume at deploy time (see docker-compose.yml). This lets you update
# models by replacing files on the host and restarting the container,
# without rebuilding the image every retraining cycle.
RUN mkdir -p /app/data/models/v1 /app/data/processed /app/logs && \
    chown -R cropai:cropai /app/data /app/logs

USER cropai

EXPOSE 8000 9090

# Default command runs the API; docker-compose overrides this for the
# worker service. Health check hits the liveness probe, not readiness —
# readiness depends on external services that may not be up yet during
# container startup ordering.
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
    CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health/live')" || exit 1

CMD ["gunicorn", "app.main:app", \
     "--workers", "4", \
     "--worker-class", "uvicorn.workers.UvicornWorker", \
     "--bind", "0.0.0.0:8000", \
     "--timeout", "30", \
     "--access-logfile", "-", \
     "--error-logfile", "-"]
