FROM node:20-slim # System deps: python3 + build tools for llama-cpp-python + curl for model download RUN apt-get update && apt-get install -y --no-install-recommends \ python3 python3-pip make g++ curl unzip \ && rm -rf /var/lib/apt/lists/* # Install llama-cpp-python server — try prebuilt first, compile if needed # CPU-only build (GGML_NATIVE=0 disables AVX/AVX2 for max compatibility) RUN CMAKE_ARGS="-DGGML_NATIVE=OFF" FORCE_CMAKE=1 \ pip3 install --break-system-packages --no-cache-dir \ "llama-cpp-python[server]" \ --prefer-binary \ --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cpu \ && echo "✅ llama-cpp-python installed!" \ || echo "⚠️ llama-cpp-python install failed — local model unavailable" WORKDIR /app RUN mkdir -p /data /app/models && chmod 777 /data # npm install (Node server deps) COPY package.json ./ RUN npm install # Pre-download TinyLlama 1.1B Q4_K_M GGUF (~637MB) # Best effort — won't fail build if download fails RUN curl -L --max-time 600 --retry 3 \ "https://huggingface.co/TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF/resolve/main/tinyllama-1.1b-chat-v1.0.Q4_K_M.gguf" \ -o /app/models/local.gguf \ && echo "✅ TinyLlama $(du -sh /app/models/local.gguf | cut -f1)" \ || echo "⚠️ Model download failed — will download at first startup" # Copy pre-built Vite dist + server COPY dist/ ./dist/ COPY server.js ./ RUN chown -R 1000:1000 /app && chmod 777 /data USER 1000 EXPOSE 7860 ENV PORT=7860 NODE_ENV=production CMD ["node", "server.js"]