Spaces:
Paused
Paused
Download Dockerfile from abc1181/loudmetric: direct link, hf CLI and curl.
- Browser
- Download file 5.18 kB
-
https://huggingface.co/spaces/abc1181/loudmetric/resolve/main/Dockerfile
- Command line
-
hf download hf://spaces/abc1181/loudmetric/Dockerfile
-
curl -L -o Dockerfile https://huggingface.co/spaces/abc1181/loudmetric/resolve/main/Dockerfile
5.18 kB
| # LoudMetric on Hugging Face Spaces. | |
| # | |
| # Two processes in one container: Postgres and the Next.js app. Spaces passes | |
| # `--port 7860`, so the app listens there while Postgres stays on a unix socket | |
| # inside the container. | |
| # | |
| # Persistence is a `pg_dump` in a Dataset repo, not a live PGDATA copy. The | |
| # runtime disk is ephemeral and Hugging Face has retired persistent storage, so a | |
| # dump on a schedule is the supported way to keep data. It also happens to be the | |
| # only safe option: PGDATA needs fsync semantics, /dev/shm and background | |
| # processes, and round-tripping a live cluster through git and LFS corrupts it. | |
| # | |
| # The honest cost of this, stated in the UI as well as here: anything written in | |
| # the last SYNC_INTERVAL minutes is lost if the Space restarts. It is a demo and | |
| # a collector, not a production database. | |
| FROM node:22-bookworm-slim | |
| # postgresql-15 for the server; postgresql-client-15 for pg_dump/pg_restore, which | |
| # run on a different schedule than the server itself. | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| postgresql-15 postgresql-client-15 ca-certificates curl \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # NODE_ENV is deliberately NOT set here. | |
| # | |
| # This was the cause of a BUILD_ERROR on the Space that took three rebuilds to | |
| # find. Setting NODE_ENV=production above `npm ci` makes npm skip | |
| # devDependencies, so typescript was never installed, and `next build` then | |
| # failed with a wall of "Module not found: Can't resolve '@/lib/db'" — an error | |
| # that looks like a missing source file or a bad path alias and is neither. | |
| # The tell was npm reporting 36 packages where a full install is 47. | |
| # | |
| # Reproduced locally by running the same two commands in that order: identical | |
| # errors, and `npm ci --include=dev` fixes it. | |
| # | |
| # NODE_ENV is set after the build, where it actually belongs: it is a runtime | |
| # concern, and setting it early only breaks the build. | |
| ENV NEXT_TELEMETRY_DISABLED=1 \ | |
| PGDATA=/var/lib/postgresql/data \ | |
| DATABASE_URL=postgres://loudmetric:loudmetric@localhost:5432/loudmetric \ | |
| PORT=7860 \ | |
| HOSTNAME=0.0.0.0 \ | |
| SYNC_INTERVAL=900 \ | |
| HF_DATASET_ID="" | |
| WORKDIR /app | |
| # Python is only here for huggingface_hub, which drives the dataset sync. | |
| RUN apt-get update && apt-get install -y --no-install-recommends python3 python3-pip \ | |
| && rm -rf /var/lib/apt/lists/* \ | |
| && pip3 install --no-cache-dir --break-system-packages "huggingface_hub>=0.24" | |
| # Dependencies first, so a source-only change does not reinstall the world. | |
| # | |
| # Full install, not --omit=dev: `next build` needs typescript and the standalone | |
| # finalize step runs a script through node, and db/seed.ts needs tsx. Installing | |
| # only runtime deps and then building was the first version of this file, and it | |
| # fails at the build step with a missing-compiler error. | |
| COPY package.json package-lock.json* ./ | |
| # --include=dev as well as the un-early NODE_ENV, because one guard against a | |
| # failure mode this subtle is not enough. Prune removes them again further down. | |
| RUN npm ci --include=dev --registry=https://registry.npmjs.org/ | |
| COPY . . | |
| RUN npm run build | |
| # Drop the toolchain now that the build is done. | |
| # | |
| # Two things fixed here, both found by an actual BUILD_ERROR on the Space: | |
| # | |
| # --registry is repeated deliberately. `npm ci` above is pinned, but prune | |
| # resolves its own tree and would otherwise hit the default registry — the one | |
| # that serves 403s and, earlier in this project's life, a truncated native | |
| # binary. It failed the whole Space build at this step. | |
| # | |
| # `|| true` because pruning is an image-size optimisation, never a | |
| # correctness requirement. A network hiccup in an optional step should cost a | |
| # few hundred megabytes, not the deployment. | |
| RUN npm prune --omit=dev --registry=https://registry.npmjs.org/ || echo "prune skipped (non-fatal)" | |
| # Runtime only, after the build. See the note at the top of this file. | |
| ENV NODE_ENV=production | |
| # Postgres refuses to run as root, so it gets its own account with its own | |
| # home. The app still runs as root, which is not great practice but matches what | |
| # Spaces expects when the container must bind 7860. | |
| RUN useradd -m -s /bin/bash postgres || true \ | |
| && mkdir -p /var/lib/postgresql/data /var/run/postgresql /dumps \ | |
| && chown -R postgres:postgres /var/lib/postgresql /var/run/postgresql \ | |
| && chmod 777 /dumps | |
| COPY hf/entrypoint.sh /usr/local/bin/loudmetric-entrypoint | |
| COPY hf/sync.py /usr/local/bin/loudmetric-sync | |
| RUN chmod +x /usr/local/bin/loudmetric-entrypoint /usr/local/bin/loudmetric-sync | |
| EXPOSE 7860 | |
| # Spaces supplies these; the sync is a no-op without them, which keeps the image | |
| # buildable and testable locally with no Hugging Face account at all. | |
| ARG HF_TOKEN="" | |
| ARG HF_DATASET_ID="" | |
| ENV HF_TOKEN=$HF_TOKEN HF_DATASET_ID=$HF_DATASET_ID | |
| # curl is in the image because of this line specifically. bookworm-slim does not | |
| # ship it, and a HEALTHCHECK whose binary is missing fails forever, which marks | |
| # a perfectly healthy Space as unhealthy. | |
| HEALTHCHECK --interval=60s --timeout=10s --start-period=90s --retries=3 \ | |
| CMD curl -fsS http://localhost:7860/api/health || exit 1 | |
| ENTRYPOINT ["/usr/local/bin/loudmetric-entrypoint"] |