File size: 3,784 Bytes
ffdb9be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
107
108
109
110
# =============================================================
# TrueNest - MLflow + FastAPI Inference Image (GeoPandas-ready)
# =============================================================

FROM python:3.10

ARG DEBIAN_FRONTEND=noninteractive

# ------------------------------------------------
# Install system deps for GeoPandas stack
# ------------------------------------------------
RUN apt-get update && apt-get install -y \
    gdal-bin \
    libgdal-dev \
    libgeos-dev \
    proj-bin \
    proj-data \
    libproj-dev \
    build-essential \
    curl \
    wget \
    && rm -rf /var/lib/apt/lists/*

ENV GDAL_DATA=/usr/share/gdal
ENV PROJ_LIB=/usr/share/proj
ENV PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1 LANG=C.UTF-8

WORKDIR /app

# ------------------------------------------------
# Copy inference code & metadata
# ------------------------------------------------
COPY ./main.py /app/main.py
COPY ./handler.py /app/handler.py
COPY ./reports /app/reports
COPY ./requirements.txt /app/requirements.txt

# ------------------------------------------------
# NEW β€” Copy source code for MLflow unpickling
# ------------------------------------------------
COPY ./src /app/src
ENV PYTHONPATH="/app"

# ------------------------------------------------
# Install Python deps
# ------------------------------------------------
RUN pip install --no-cache-dir --upgrade pip setuptools wheel
RUN pip install --no-cache-dir uvicorn fastapi python-dotenv
RUN pip install --no-cache-dir -r /app/requirements.txt

EXPOSE 7860

# ------------------------------------------------
# Startup script with GCP credential fix
# ------------------------------------------------
RUN printf '%s\n' \
  '#!/bin/bash' \
  'set -e' \
  'echo "πŸš€ Starting TrueNest GeoPandas-enabled inference container"' \
  '' \
  '# -------------------------------' \
  '# Configure GCP credentials' \
  '# -------------------------------' \
  'if [ -n "$GOOGLE_APPLICATION_CREDENTIALS_JSON" ]; then' \
  '  echo "$GOOGLE_APPLICATION_CREDENTIALS_JSON" > /tmp/creds.json' \
  '  export GOOGLE_APPLICATION_CREDENTIALS=/tmp/creds.json' \
  '  export CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=/tmp/creds.json' \
  '  echo "βœ… GCP credentials written to /tmp/creds.json"' \
  'else' \
  '  echo "⚠️ No GOOGLE_APPLICATION_CREDENTIALS_JSON provided. GCS access will fail."' \
  'fi' \
  '' \
  '# -------------------------------' \
  '# Force GCP credential load BEFORE MLflow loads model' \
  'echo "πŸ” Verifying GCP credentials..."' \
  'python <<EOF' \
  'import os' \
  'from google.oauth2 import service_account' \
  'from google.cloud import storage' \
  'p = os.getenv("GOOGLE_APPLICATION_CREDENTIALS")' \
  'if not p or not os.path.exists(p):' \
  '    print("❌ No valid Google credentials found:", p)' \
  'else:' \
  '    creds = service_account.Credentials.from_service_account_file(p)' \
  '    client = storage.Client(credentials=creds)' \
  '    try:' \
  '        client.list_buckets(max_results=1)' \
  '        print("πŸ” GCP credentials verified successfully")' \
  '    except Exception as e:' \
  '        print("❌ GCP credential test failed:", e)' \
  'EOF' \
  '' \
  '# -------------------------------' \
  '# Preload MLflow pipeline model' \
  '# -------------------------------' \
  'python <<EOF' \
  'import mlflow, json' \
  'info = json.load(open("/app/reports/last_run_info.json"))' \
  'uri = info.get("pipeline_model_uri") or info.get("model_uri")' \
  'print(f"πŸ“¦ Loading MLflow model: {uri}")' \
  'mlflow.pyfunc.load_model(uri)' \
  'print("βœ… MLflow model loaded successfully")' \
  'EOF' \
  '' \
  'echo "πŸš€ Launching FastAPI server"' \
  'exec uvicorn main:app --host 0.0.0.0 --port 7860' \
  > /app/start.sh && chmod +x /app/start.sh

CMD ["/app/start.sh"]