mtg-deck-completion / Dockerfile
nsaroiu's picture
Deploy c769859
5f4fccd verified
Raw History Blame Contribute Delete
2.53 kB
# Production image: builds the React frontend, then serves it and the API
# from one uvicorn process. Also what the Hugging Face Space builds (see
# deploy/push_space.py).
#
# Everything the app downloads is baked in at build time: the model files,
# card stats, and prices. The model is pinned to one Hub commit
# (MODEL_REVISION below), and the running container never changes it
# (MTG_MODEL_UPDATE=0), so a deploy is reproducible. To ship a new model
# release, bump MODEL_REVISION in a commit (see README, "Updating the
# model"); rolling back is reverting that commit. Prices still refresh in
# the background once they're a day old.
#
# docker build -t mtg-deck-completion-web .
# docker run -p 8000:8000 mtg-deck-completion-web
FROM node:22-slim AS web
WORKDIR /web
COPY web/package.json web/package-lock.json ./
RUN npm ci
COPY web/ ./
RUN npm run build
FROM python:3.14-slim
ENV PIP_NO_CACHE_DIR=1 PYTHONUNBUFFERED=1
# CPU-only torch wheel: the default one bundles CUDA and is several GB larger.
RUN pip install torch==2.14.0 --index-url https://download.pytorch.org/whl/cpu
COPY requirements-server.txt ./
RUN pip install -r requirements-server.txt
# Spaces runs the container as uid 1000, and the app writes to data/ (price
# refreshes), so the app directory belongs to that user.
RUN useradd -m -u 1000 user && mkdir /app && chown user:user /app
USER user
ENV HOME=/home/user
WORKDIR /app
COPY --chown=user scryfall_bulk.py ./
COPY --chown=user tokenizer/ tokenizer/
COPY --chown=user training/ training/
COPY --chown=user server/ server/
# The model release this image serves: a commit sha (or tag) of the Hub repo
# nsaroiu/mtg-deck-completion. The selfcheck loads it and builds a deck, so
# a release this code can't load fails the build, not the running app. The
# download's staging copy (data/.model-snapshot) is only needed for later
# updates, which this image never does, so it's dropped in the same layer.
ARG MODEL_REVISION=52756aa56863c6ce5a9a40325041034667bce2c4
RUN MTG_MODEL_REVISION=$MODEL_REVISION python -m server.model_files \
&& rm -rf data/.model-snapshot \
&& python -m server.selfcheck
RUN python -m server.card_stats && python -m server.card_prices
COPY --chown=user --from=web /web/dist web/dist
# Torch sizes its thread pool from the host's cores, not the container's
# share; match the vCPUs actually available (2 on a free Space).
ENV MTG_MODEL_UPDATE=0 MTG_API_DOCS=0 OMP_NUM_THREADS=2
EXPOSE 8000
CMD ["uvicorn", "server.app:app", "--host", "0.0.0.0", "--port", "8000"]