| |
| |
| FROM python:3.11-slim |
|
|
| |
| ENV DEBIAN_FRONTEND=noninteractive |
| ENV PYTHONUNBUFFERED=1 |
| ENV OLLAMA_HOST=0.0.0.0 |
| ENV PORT=7860 |
| ENV HF_HOME=/data |
| ENV TRANSFORMERS_CACHE=/data/transformers_cache |
|
|
| |
| RUN apt-get update && apt-get install -y \ |
| curl \ |
| ca-certificates \ |
| && rm -rf /var/lib/apt/lists/* |
|
|
| |
| RUN curl -fsSL https://ollama.ai/install.sh | sh |
|
|
| |
| WORKDIR /app |
| COPY . . |
|
|
| |
| RUN pip install --no-cache-dir fastapi uvicorn python-multipart aiohttp |
|
|
| |
| RUN mkdir -p /root/.ollama |
|
|
| |
| |
|
|
| |
| COPY <<EOF /app/start.sh |
| |
| echo "🚀 Starting Jaksel AI on Hugging Face Spaces..." |
|
|
| |
| mkdir -p /root/.ollama |
|
|
| |
| echo "📥 Starting Ollama server..." |
| ollama serve --host 0.0.0.0 --port 11434 & |
|
|
| |
| echo "⏳ Waiting for Ollama to start..." |
| sleep 10 |
|
|
| |
| echo "🤖 Pulling Jaksel model..." |
| ollama pull zantara-jaksel:latest || echo "Model already exists or download failed, continuing..." |
|
|
| |
| if ! ollama list | grep -q "zantara-jaksel"; then |
| echo "🔄 Retrying model download..." |
| sleep 5 |
| ollama pull zantara-jaksel:latest |
| fi |
|
|
| |
| python <<PYTHON |
| import subprocess |
| import time |
| import requests |
| from fastapi import FastAPI, Request |
| import uvicorn |
| import json |
|
|
| app = FastAPI(title="Jaksel AI Proxy") |
|
|
| @app.get("/") |
| async def root(): |
| return {"message": "Jaksel AI is running!", "status": "healthy"} |
|
|
| @app.get("/health") |
| async def health(): |
| try: |
| response = requests.get("http://127.0.0.1:11434/api/tags", timeout=5) |
| if response.status_code == 200: |
| models = response.json().get("models", []) |
| jaksel_found = any("zantara-jaksel" in m.get("name", "") for m in models) |
| return { |
| "status": "healthy", |
| "ollama": "connected", |
| "jaksel_loaded": jaksel_found, |
| "models": [m.get("name") for m in models] |
| } |
| else: |
| return {"status": "unhealthy", "ollama": "error"} |
| except Exception as e: |
| return {"status": "unhealthy", "error": str(e)} |
|
|
| @app.post("/api/generate") |
| @app.post("/api/chat") |
| async def proxy_ollama(request: Request): |
| """Proxy per richieste a Ollama""" |
| try: |
| |
| body = await request.json() |
|
|
| |
| ollama_url = "http://127.0.0.1:11434" + request.scope.get("path", "") |
|
|
| response = requests.post( |
| ollama_url, |
| json=body, |
| headers={ |
| "Content-Type": "application/json", |
| }, |
| timeout=120 |
| ) |
|
|
| return Response( |
| content=response.content, |
| status_code=response.status_code, |
| headers={ |
| "Content-Type": "application/json", |
| } |
| ) |
| except Exception as e: |
| return { |
| "error": f"Proxy error: {str(e)}", |
| "response": "Maaf, Jaksel lagi nggak bisa merespon. Coba lagi ya!" |
| } |
|
|
| from fastapi.responses import Response |
|
|
| print("🌐 Starting proxy server on port 7860...") |
| uvicorn.run(app, host="0.0.0.0", port=7860) |
| PYTHON |
|
|
| |
| sleep 30 |
| EOF |
|
|
| |
| RUN chmod +x /app/start.sh |
|
|
| |
| EXPOSE 7860 11434 |
|
|
| |
| CMD ["/app/start.sh"] |