fashionistar-celery-queues / Dockerfile.production
FASHIONISTAR CI/CD
🔄 Celery Queues Deploy: d915798567b1052828794606dda8e62b4500f337 [GitHub Actions]
607bf71
Raw
History Blame Contribute Delete
4.43 kB
# =============================================================================
# FASHIONISTAR — Production Dockerfile (Hugging Face Spaces)
# =============================================================================
# Target: Hugging Face Spaces (Docker SDK — linux/amd64)
# Port: 7860 (HF mandatory) | UID: 1000 (HF mandatory)
#
# HF Spaces Dev Mode requirements (PRO plan):
# ✓ bash, git, git-lfs, curl, wget, procps installed
# ✓ /app owned by UID 1000
# ✓ CMD instruction present
# ✓ Debian-based image (python:3.13-slim ✓)
# =============================================================================
# ── Stage 1: uv binary ───────────────────────────────────────────────────────
# Versions are hardcoded (NOT ARG) because HF Spaces injects Space secrets as
# Docker build args, overriding ARG defaults and causing build failures.
FROM ghcr.io/astral-sh/uv:0.8.22 AS uvbin
# ── Stage 2: dependency builder ──────────────────────────────────────────────
FROM python:3.13-slim AS builder
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
UV_COMPILE_BYTECODE=1 \
UV_LINK_MODE=copy \
UV_PROJECT_ENVIRONMENT=/opt/venv
# Build-time system dependencies (libpq-dev for psycopg compilation)
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
COPY --from=uvbin /uv /uvx /bin/
WORKDIR /app
# Copy dependency manifests first (layer caching — only rebuilds if these change)
COPY pyproject.toml uv.lock ./
# Install production dependencies into /opt/venv
RUN uv sync --frozen --no-dev --no-editable --no-install-project
# ── Stage 3: production runtime ───────────────────────────────────────────────
FROM python:3.13-slim AS runner
# Runtime environment
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
UV_LINK_MODE=copy \
UV_PROJECT_ENVIRONMENT=/opt/venv \
PATH="/opt/venv/bin:$PATH" \
DJANGO_SETTINGS_MODULE=backend.config.production \
WORKING_ENVIRONMENT=production \
PORT=7860 \
OLLAMA_ENABLED=True \
UVICORN_WS=auto \
GUNICORN_WORKERS=3 \
GUNICORN_TIMEOUT=900 \
GUNICORN_KEEPALIVE=900 \
GUNICORN_MAX_REQUESTS=1000 \
GUNICORN_MAX_REQUESTS_JITTER=100 \
GUNICORN_LOG_LEVEL=info
# Runtime system dependencies
# IMPORTANT: bash, git, git-lfs, wget, procps are REQUIRED for HF Spaces Dev Mode (PRO plan).
# Without them, Dev Mode injects `RUN git config ...` steps that fail with "git: not found".
# curl + zstd needed for Ollama install. libpq5 for psycopg runtime.
RUN apt-get update && apt-get install -y --no-install-recommends \
libpq5 \
postgresql-client \
curl \
wget \
zstd \
bash \
dos2unix \
git \
git-lfs \
procps \
&& git lfs install \
&& curl -fsSL https://ollama.com/install.sh | sh \
&& rm -rf /var/lib/apt/lists/*
COPY --from=uvbin /uv /uvx /bin/
COPY --from=builder /opt/venv /opt/venv
# Create non-root app user (UID 1000 — MANDATORY for HF Spaces)
RUN useradd --create-home --uid 1000 --shell /bin/bash appuser && \
mkdir -p /app/staticfiles /app/media /app/logs /home/appuser/.ollama && \
chown -R appuser:appuser /app /home/appuser
WORKDIR /app
# Copy application source (after deps — maximizes layer cache hits)
COPY --chown=appuser:appuser . .
# Copy entrypoint and make executable (must be done as root before USER switch)
# dos2unix strips Windows CRLF (\r\n) → LF (\n) to prevent "sh: 1: api: not found"
COPY --chown=appuser:appuser entrypoint.sh /entrypoint.sh
RUN dos2unix /entrypoint.sh && chmod +x /entrypoint.sh
USER appuser
# NOTE: Ollama models (llama3.2, nomic-embed-text) are pulled at RUNTIME
# by entrypoint.sh on first start, in a background process so the API
# starts immediately. HF persistent disk caches them for instant restarts.
# Port 7860 — mandatory for HF Spaces
EXPOSE 7860
# Health check
HEALTHCHECK --interval=30s --timeout=15s --start-period=120s --retries=3 \
CMD curl -fsS "http://127.0.0.1:${PORT:-7860}/api/v1/health/" || exit 1
ENTRYPOINT ["/entrypoint.sh"]
CMD ["api"]