File size: 3,524 Bytes
57559fb 41788c4 57559fb 41788c4 57559fb 41788c4 57559fb b1a38a9 57559fb 41788c4 57559fb b1a38a9 57559fb 41788c4 57559fb 41788c4 57559fb 41788c4 57559fb 41788c4 57559fb 41788c4 57559fb b1a38a9 57559fb 41788c4 57559fb 41788c4 57559fb 41788c4 57559fb 41788c4 fbf0154 41788c4 57559fb | 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 | # syntax=docker/dockerfile:1.7
# -----------------------------------------------------------------------------
# Docsifer โ multi-stage image (CPU-only, HF Spaces compatible).
#
# Stage 1 builder compiles wheels from requirements.txt into /install
# Stage 2 runtime slim image with jemalloc + healthcheck + non-root user
#
# Build:
# docker build -t docsifer .
# Run:
# docker run --rm -p 7860:7860 --env-file .env docsifer
# -----------------------------------------------------------------------------
ARG PYTHON_VERSION=3.11
# ============================================================================
# Stage 1: builder
# ============================================================================
FROM python:${PYTHON_VERSION}-slim AS builder
ENV PIP_DISABLE_PIP_VERSION_CHECK=1 \
PIP_NO_CACHE_DIR=0 \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
# Build tools required by source-only wheels (e.g. python-magic, tiktoken).
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && apt-get install -y --no-install-recommends \
build-essential git ca-certificates libmagic1
WORKDIR /build
COPY requirements.txt ./
RUN --mount=type=cache,target=/root/.cache/pip,sharing=locked \
pip install --prefix=/install -r requirements.txt
# ============================================================================
# Stage 2: runtime
# ============================================================================
FROM python:${PYTHON_VERSION}-slim AS runtime
LABEL org.opencontainers.image.title="docsifer" \
org.opencontainers.image.description="Document โ Markdown service powered by MarkItDown" \
org.opencontainers.image.licenses="MIT" \
org.opencontainers.image.source="https://github.com/lh0x00/docsifer"
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1 \
OMP_NUM_THREADS=2 \
MKL_NUM_THREADS=2 \
TOKENIZERS_PARALLELISM=false \
HF_HOME=/home/user/.cache/huggingface \
XDG_CACHE_HOME=/home/user/.cache \
TMPDIR=/tmp \
DOCSIFER_TMP_DIR=/tmp \
DOCSIFER_LOG_JSON=true \
DOCSIFER_ENVIRONMENT=production \
PORT=7860
# jemalloc keeps RSS predictable for workloads with frequent (de)allocations
# (markitdown / ffmpeg / pillow chains all churn the heap).
# libmagic1 + ffmpeg are required at runtime by python-magic and audio
# transcription respectively. curl is used by HEALTHCHECK.
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && apt-get install -y --no-install-recommends \
libjemalloc2 libmagic1 ffmpeg ca-certificates curl
ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
# Non-root. Hugging Face Spaces requires uid 1000 with write access to /home/user.
RUN useradd -m -u 1000 user
USER user
WORKDIR /home/user/app
# Pull the prebuilt site-packages from stage 1.
COPY --from=builder /install /usr/local
# Application source.
COPY --chown=user . .
# Ensure HF cache dirs exist (Spaces / restricted FS).
RUN mkdir -p "$HF_HOME" "$XDG_CACHE_HOME"
EXPOSE 7860
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
CMD curl -fsS "http://127.0.0.1:${PORT}/v1/healthz" >/dev/null || exit 1
CMD ["uvicorn", "docsifer.main:app", \
"--host", "0.0.0.0", \
"--port", "7860", \
"--proxy-headers", \
"--forwarded-allow-ips", "*"]
|