Samoed commited on
Commit
051ff64
Β·
verified Β·
1 Parent(s): a97af5d

Update Dockerfile

Browse files
Files changed (1) hide show
  1. Dockerfile +113 -25
Dockerfile CHANGED
@@ -1,17 +1,40 @@
1
  # syntax=docker/dockerfile:1.7
2
- # Hugging Face Spaces Dockerfile for the mteb FastAPI service.
3
  #
4
- # Clones embeddings-benchmark/mteb @ api, installs the project with its
5
- # [api] extra (fastapi + uvicorn), and serves it on :7860 as the
6
- # non-root `user` (UID 1000) that Spaces expects.
7
  #
8
- # Everything is hardcoded β€” Spaces does not pass build args. Edit and
9
- # rebuild to change repo or branch.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
- FROM python:3.12-bookworm
 
12
 
 
 
 
 
 
13
  RUN apt-get update \
14
- && apt-get install -y --no-install-recommends git curl build-essential \
15
  && rm -rf /var/lib/apt/lists/* \
16
  && useradd -m -u 1000 user
17
 
@@ -24,29 +47,94 @@ ENV PATH="/home/user/.local/bin:$PATH" \
24
  HF_HOME=/home/user/.cache/huggingface \
25
  XDG_CACHE_HOME=/home/user/.cache
26
 
27
- # Frontend Space origin allowed through CORS. Add others comma-separated
28
- # if you front this API with a different host.
29
- ENV MTEB_API_CORS_ORIGINS="https://mteb-leaderboardv3.hf.space,http://localhost:5173,http://localhost:4173"
30
-
31
  USER user
32
  WORKDIR /home/user
33
 
34
- RUN git clone --depth=1 --branch api \
35
- https://github.com/embeddings-benchmark/mteb.git app
 
 
 
36
  WORKDIR /home/user/app
37
 
38
  # Branches that define an [api] extra get fastapi + uvicorn from it; on
39
- # older branches the explicit pins are the fallback.
40
- RUN pip install --user ".[api]" \
41
- || pip install --user . "fastapi>=0.110" "uvicorn[standard]>=0.27"
42
-
43
- # Pre-warm the HF dataset cache from mteb/results so the first request
44
- # doesn't have to clone the GitHub repo from cold. Goes to the
45
- # huggingface_hub default cache under $HF_HOME. `|| true` keeps the
46
- # build alive while the dataset is still being populated upstream β€”
47
- # the API falls back to the GitHub clone on first request when the
48
- # snapshot is empty.
49
- RUN hf download mteb/results_new --repo-type dataset || true
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
  EXPOSE 7860
52
 
 
1
  # syntax=docker/dockerfile:1.7
 
2
  #
3
+ # Multi-stage Dockerfile for the mteb FastAPI service.
 
 
4
  #
5
+ # Three stages share the heavy "clone + pip install + HF dataset
6
+ # warmup" work via a common base image:
7
+ #
8
+ # base β€” python:3.12-bookworm + git + a non-root user + mteb
9
+ # cloned and installed with the [api] extra + the
10
+ # mteb/results parquet cache pre-warmed.
11
+ # og-builder β€” extends `base` with Chromium runtime libs + the
12
+ # [og] extra (Playwright). Renders one OG hero PNG per
13
+ # benchmark / task / model into /og-cache, then exits.
14
+ # Nothing downstream of this stage ships.
15
+ # runtime β€” extends `base`, copies the rendered PNG files out of
16
+ # og-builder. Stays small: no Playwright, no Chromium,
17
+ # no Node. FastAPI serves the cached PNG files at /og.
18
+ #
19
+ # Result: the deployed image is the lean base + ~50 MB of pre-rendered
20
+ # PNG files, not the ~700 MB hit of baking Chromium into runtime. The repo
21
+ # is cloned once, [api] is installed once, the HF dataset cache is
22
+ # downloaded once β€” both downstream stages reuse the same layers.
23
+
24
+ ARG MTEB_BRANCH=api
25
+ ARG MTEB_REPO=https://github.com/embeddings-benchmark/mteb.git
26
+
27
 
28
+ # ─── Stage: base ────────────────────────────────────────────────────
29
+ FROM python:3.12-bookworm AS base
30
 
31
+ ARG MTEB_BRANCH
32
+ ARG MTEB_REPO
33
+
34
+ # Just enough to clone + build pip wheels. Chromium libs are added in
35
+ # the og-builder stage so the runtime layer doesn't carry them.
36
  RUN apt-get update \
37
+ && apt-get install -y --no-install-recommends git curl build-essential ca-certificates \
38
  && rm -rf /var/lib/apt/lists/* \
39
  && useradd -m -u 1000 user
40
 
 
47
  HF_HOME=/home/user/.cache/huggingface \
48
  XDG_CACHE_HOME=/home/user/.cache
49
 
 
 
 
 
50
  USER user
51
  WORKDIR /home/user
52
 
53
+ # Bust the clone cache whenever the API branch advances upstream. The
54
+ # ADD response (latest commit SHA) changes per push, so Docker can no
55
+ # longer reuse a stale checkout when you rebuild.
56
+ ADD --chown=user:user https://api.github.com/repos/embeddings-benchmark/mteb/commits/${MTEB_BRANCH} /tmp/.git-sha
57
+ RUN git clone --depth=1 --branch ${MTEB_BRANCH} ${MTEB_REPO} app
58
  WORKDIR /home/user/app
59
 
60
  # Branches that define an [api] extra get fastapi + uvicorn from it; on
61
+ # older branches the explicit pins are the fallback. The PyTorch CPU
62
+ # wheel index is added alongside default PyPI so the torch / torchvision
63
+ # / torchaudio transitive deps resolve to ``2.x.x+cpu`` (~200 MB total)
64
+ # instead of the default CUDA wheels (~2 GB across torch +
65
+ # nvidia-cu* deps). PEP 440 ranks the ``+cpu`` local version above the
66
+ # plain release, so pip picks it without an explicit version pin.
67
+ RUN pip install --user --extra-index-url https://download.pytorch.org/whl/cpu ".[api]" \
68
+ || pip install --user --extra-index-url https://download.pytorch.org/whl/cpu . \
69
+ "fastapi>=0.110" "uvicorn[standard]>=0.27"
70
+
71
+ # Pre-warm the HF dataset cache from mteb/results so the OG builder
72
+ # (which calls warmup_blocking()) and the runtime first request both
73
+ # skip the multi-minute cold clone. `|| true` keeps the build alive
74
+ # when the dataset is still being populated upstream β€” the API falls
75
+ # back to the GitHub clone on first request when the snapshot is empty.
76
+ RUN hf download mteb/results --repo-type dataset || true
77
+
78
+
79
+ # ─── Stage: og-builder ────────────────────────────────────────────���─
80
+ FROM base AS og-builder
81
+
82
+ ENV PLAYWRIGHT_BROWSERS_PATH=/home/user/.cache/playwright \
83
+ MTEB_API_OG_DIR=/og-cache
84
+
85
+ # Chromium runtime libs Playwright drives. Listing them explicitly
86
+ # instead of running `playwright install --with-deps` keeps the layer
87
+ # cacheable across rebuilds (the deps list rarely changes).
88
+ USER root
89
+ RUN apt-get update \
90
+ && apt-get install -y --no-install-recommends \
91
+ libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 \
92
+ libxkbcommon0 libatspi2.0-0 libxcomposite1 libxdamage1 \
93
+ libxfixes3 libxrandr2 libgbm1 libdrm2 libasound2 \
94
+ fonts-noto-color-emoji fonts-liberation \
95
+ && rm -rf /var/lib/apt/lists/* \
96
+ && mkdir -p /og-cache && chown user:user /og-cache
97
+ USER user
98
+
99
+ # Add Playwright on top of the [api] install already in base. We
100
+ # install the bare package instead of re-resolving ``.[og]`` because
101
+ # pip will skip extras when ``.`` is already "satisfied" from the
102
+ # base stage's install, which silently drops playwright. Pinning the
103
+ # bare package guarantees it lands.
104
+ RUN pip install --user "playwright>=1.49.0"
105
+ # Invoke via ``python -m playwright`` instead of the ``playwright``
106
+ # shim β€” the shim lives at /home/user/.local/bin/playwright and
107
+ # ``$PATH`` does include that directory, but Docker's ``RUN`` shells
108
+ # sometimes resolve PATH before the pip layer's new bin entry is
109
+ # visible. ``-m`` skips the shim entirely and is the recommended
110
+ # invocation in Playwright's own Docker docs.
111
+ RUN python -m playwright install chromium
112
+
113
+ # Render every per-entity OG card. The script imports the mteb
114
+ # registry directly (no HTTP, no uvicorn boot) and loads the template
115
+ # from a file:// URL under scripts/og-template/, so this is a single
116
+ # self-contained Python invocation. Output lands in /og-cache and the
117
+ # runtime stage copies it out.
118
+ RUN python scripts/generate_og_images.py --out=/og-cache
119
+
120
+
121
+ # ─── Stage: runtime ─────────────────────────────────────────────────
122
+ FROM base AS runtime
123
+
124
+ ENV MTEB_API_OG_DIR=/data/og
125
+
126
+ # Frontend Space origin allowed through CORS. Add others comma-separated
127
+ # if you front this API with a different host.
128
+ ENV MTEB_API_CORS_ORIGINS="https://mteb-leaderboardv2.hf.space,http://localhost:5173,http://localhost:4173"
129
+
130
+ # Mount point for the rendered OG hero PNG files. /data is the conventional
131
+ # Spaces persistent-volume mount: if Spaces mounts an empty volume over
132
+ # /data at runtime, the served /og 404s until someone re-runs the
133
+ # generator. With no mount, the baked-in cache wins.
134
+ USER root
135
+ RUN mkdir -p /data/og && chown -R user:user /data
136
+ COPY --from=og-builder --chown=user:user /og-cache /data/og
137
+ USER user
138
 
139
  EXPOSE 7860
140