DocEditorPlayground / Dockerfile
Eric Putnam
Claude Opus 5 (1M context)
feat: deploy DocEditorPlayground as a static Hugging Face Space
8a8c5bb
Raw History Blame Contribute Delete
2.91 kB
# NOT what the Hugging Face Space uses.
#
# The Space is a Static Space (sdk: static in README.md), because creating Docker
# Spaces requires a paid Hugging Face plan. This file is kept for two cases:
#
# 1. Running the app as a real Next.js server locally:
# docker build -t dep-space .
# docker run --rm -p 7860:7860 dep-space
# 2. Switching the Space to the Docker SDK later, on a paid plan - which is
# also what giving /api/ai-suggest a real server-side LLM call would need,
# since a static page cannot hold an API key.
#
# Unlike the static build, this serves upstream unmodified: the real
# /api/ai-suggest route runs and overlay/ is not applied.
#
# The app itself lives in ./app, a vendored mirror of the upstream repo (see
# UPSTREAM.json). Refresh it with scripts/sync-upstream.ps1 - never hand-edit
# files under ./app, those edits are wiped on the next sync.
# Pinned to match app/.nvmrc. sync-upstream.ps1 warns when the two drift.
FROM node:20.19.3-bookworm-slim
# git is required at install time: package-lock.json resolves two dependencies
# straight from GitHub (mark-review, y-webrtc) instead of the npm registry.
RUN apt-get update \
&& apt-get install -y --no-install-recommends git ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Hugging Face convention: run as a non-root uid 1000.
RUN useradd -m -u 1000 user
USER user
ENV HOME=/home/user \
PATH=/home/user/.local/bin:$PATH \
NODE_ENV=production \
NEXT_TELEMETRY_DISABLED=1 \
PORT=7860 \
HOSTNAME=0.0.0.0
# mkdir explicitly rather than letting WORKDIR create it: unlike the FSV Space,
# this build writes into the workdir (next build emits .next/), and a
# WORKDIR-created directory is not guaranteed to be owned by the active USER.
RUN mkdir -p $HOME/app
WORKDIR $HOME/app
# Those two GitHub dependencies are pinned as git+ssh:// URLs, which need an SSH
# key we do not have in the build. Rewrite them to anonymous https:// — both
# upstream repos are public. --add keeps all three URL spellings npm may emit.
RUN git config --global --add url."https://github.com/".insteadOf "ssh://git@github.com/" \
&& git config --global --add url."https://github.com/".insteadOf "git+ssh://git@github.com/" \
&& git config --global --add url."https://github.com/".insteadOf "git@github.com:"
# Manifests first so the dependency layer survives source-only changes.
COPY --chown=user app/package.json app/package-lock.json app/.npmrc ./
# --include=dev overrides NODE_ENV=production above: the build genuinely needs
# devDependencies (typescript, and @next/bundle-analyzer which next.config.js
# imports at startup), so they stay in the runtime image too.
RUN npm ci --include=dev --no-audit --no-fund
COPY --chown=user app/ ./
RUN npm run build \
&& npm cache clean --force
EXPOSE 7860
CMD ["./node_modules/.bin/next", "start", "-p", "7860", "-H", "0.0.0.0"]