Agromind-backend / Dockerfile
gh-action-hf-sync
sync: backend from github@cc8365e9
cfbb235
Raw
History Blame Contribute Delete
3.13 kB
# Unified Dockerfile for Hugging Face Spaces deployment
# Runs BOTH the Node.js backend (port 7860) and the Python AI backend (port 5000)
# in a single container so ML model requests are proxied to localhost:5000.
FROM node:22-bookworm-slim
WORKDIR /app
# Install Python 3, pip and build deps needed by both stacks
RUN apt-get update && apt-get install -y --no-install-recommends \
python3 \
python3-pip \
python3-sklearn \
build-essential \
pkg-config \
wget \
curl \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# ── Node.js backend ──────────────────────────────────────────────────────────
COPY backend/package*.json ./
ENV NODE_ENV=production
RUN npm install --omit=dev
COPY backend/ ./
# ── Python AI backend ────────────────────────────────────────────────────────
COPY ai-backend/requirements.txt /ai-backend/requirements.txt
RUN pip3 install --no-cache-dir --break-system-packages -r /ai-backend/requirements.txt
COPY ai-backend/ /ai-backend/
# Point the Node backend at the co-located AI service
ENV AI_BACKEND_URL=http://localhost:5000
# ── Create non-root user (uid 1000) for HF Spaces ───────────────────────────
RUN set -ex && \
if ! getent group 1000 > /dev/null 2>&1; then \
groupadd -g 1000 nodejs; \
fi && \
GROUP_NAME=$(getent group 1000 | cut -d: -f1) && \
if ! getent passwd 1000 > /dev/null 2>&1; then \
useradd -m -u 1000 -g ${GROUP_NAME} appuser; \
fi && \
chown -R 1000:1000 /app /ai-backend
# ── Startup script ───────────────────────────────────────────────────────────
# Launches the Python AI backend in the background, then starts Node.js
COPY <<'EOF' /start.sh
#!/bin/sh
echo "[startup] Starting AI backend on port 5000..."
cd /ai-backend && gunicorn --bind 0.0.0.0:5000 --workers 2 --timeout 180 --preload app:app &
AI_PID=$!
# Wait for AI backend to be ready (up to 30 s)
READY=0
for i in $(seq 1 30); do
if wget -q --spider http://127.0.0.1:5000/health 2>/dev/null; then
echo "[startup] AI backend is ready."
READY=1
break
fi
# Exit if the AI backend process died during startup
if ! kill -0 $AI_PID 2>/dev/null; then
echo "[startup] AI backend process exited unexpectedly."
break
fi
sleep 1
done
if [ "$READY" -eq 0 ] && kill -0 $AI_PID 2>/dev/null; then
echo "[startup] AI backend health check timed out after 30s; proceeding anyway."
fi
echo "[startup] Starting Node.js backend on port 7860..."
cd /app && exec node server.js
EOF
RUN chmod +x /start.sh
USER 1000
EXPOSE 7860
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:7860/health || exit 1
CMD ["/start.sh"]