Spaces:
Paused
Paused
Download Dockerfile from jerrdeh/muscriptor-chords: direct link, hf CLI and curl.
- Browser
- Download file 4.14 kB
-
https://huggingface.co/spaces/jerrdeh/muscriptor-chords/resolve/main/Dockerfile
- Command line
-
hf download hf://spaces/jerrdeh/muscriptor-chords/Dockerfile
-
curl -L -o Dockerfile https://huggingface.co/spaces/jerrdeh/muscriptor-chords/resolve/main/Dockerfile
4.14 kB
| # Image for the "muscriptor-chords" Hugging Face Docker Space (see the README | |
| # next to this file). The build context is the *repository root*, not this | |
| # directory: the image installs the real `muscriptor` package from the checkout | |
| # so the Space runs the same chord recognition code as the main server rather | |
| # than a copy of it. Build it locally with: | |
| # | |
| # docker build -f deploy/huggingface/Dockerfile -t muscriptor-chords . | |
| # | |
| # and the sync workflow lays the Space repo out the same way (this file copied | |
| # to the Space root, the rest of the tree kept where it is). | |
| FROM python:3.11-slim | |
| # ffmpeg and libsndfile1 are what soundfile/librosa call out to for anything | |
| # that is not a PCM WAV β mp3, m4a, ogg, flac. Everything else the service | |
| # needs is a wheel. | |
| RUN apt-get update \ | |
| && apt-get install -y --no-install-recommends \ | |
| ffmpeg \ | |
| libsndfile1 \ | |
| ca-certificates \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # A Space runs as a non-root user, so every path the process writes to has to | |
| # belong to it: HOME (where `muscriptor.utils.download` caches the BTC | |
| # checkpoint), the HF hub cache (where beat_this's checkpoint lands β the | |
| # default /root/.cache is not writable here) and numba's cache, which librosa | |
| # fills on first use. | |
| ENV HOME=/home/app \ | |
| HF_HOME=/home/app/.cache/huggingface \ | |
| XDG_CACHE_HOME=/home/app/.cache \ | |
| NUMBA_CACHE_DIR=/home/app/.cache/numba \ | |
| PYTHONUNBUFFERED=1 \ | |
| PIP_NO_CACHE_DIR=1 \ | |
| PIP_DISABLE_PIP_VERSION_CHECK=1 | |
| RUN useradd --uid 10001 --create-home --home-dir /home/app --shell /usr/sbin/nologin app \ | |
| && mkdir -p /home/app/.cache /app \ | |
| && chown -R 10001:10001 /home/app /app | |
| WORKDIR /app | |
| # torch and torchaudio come from PyTorch's CPU index, pinned to the versions | |
| # uv.lock resolves. The default PyPI wheels bundle CUDA β over 2 GB of it β for | |
| # a Space that will only ever run `torch.device("cpu")`. Bump these together | |
| # when the lockfile moves; they must stay a matched pair. | |
| ARG TORCH_VERSION=2.13.0 | |
| ARG TORCHAUDIO_VERSION=2.11.0 | |
| RUN pip install --no-cache-dir --index-url https://download.pytorch.org/whl/cpu \ | |
| "torch==${TORCH_VERSION}" "torchaudio==${TORCHAUDIO_VERSION}" | |
| # uv is the project's package manager; here it is used only as a fast pip that | |
| # can install a pyproject's dependencies without its source, so the dependency | |
| # layer survives every change to muscriptor's own code. Nothing resolves torch | |
| # again: the CPU build above already satisfies the `torch>=2.3` floor. | |
| COPY --from=ghcr.io/astral-sh/uv:0.12.3 /uv /usr/local/bin/uv | |
| COPY pyproject.toml uv.lock ./ | |
| RUN uv pip install --system --no-cache -r pyproject.toml | |
| # README.md and LICENSE are not documentation here β hatchling reads both while | |
| # building the wheel (`readme` and `license-files` in pyproject.toml), and the | |
| # build fails without them. | |
| COPY README.md LICENSE ./ | |
| COPY muscriptor/ ./muscriptor/ | |
| COPY deploy/huggingface/app.py ./app.py | |
| RUN uv pip install --system --no-cache --no-deps . | |
| USER 10001 | |
| # Bake the model weights into the image, the way the root Dockerfile pre-warms | |
| # the soundfonts: a Space that has gone to sleep must not spend its first | |
| # request downloading 12 MB of checkpoint and verifying it. `_checkpoint_path` | |
| # is the same download-and-check-the-digest path the service uses at runtime, | |
| # so a tampered or truncated download fails the build rather than the request. | |
| # The beat tracker's checkpoint is best-effort β it is a separate host, and | |
| # chords without a beat grid are still chords. | |
| RUN python -c "from muscriptor.utils.chords import _checkpoint_path; print('BTC checkpoint at', _checkpoint_path())" \ | |
| && (python -c "from beat_this.inference import Audio2Beats; Audio2Beats(checkpoint_path='final0', device='cpu')" \ | |
| || echo 'warning: beat tracker checkpoint not pre-fetched; it downloads on first use') | |
| # 7860 is the port Hugging Face routes a Docker Space to (app_port in the | |
| # README frontmatter). One worker on purpose: the concurrency cap, the rate | |
| # limiter and the loaded model are all per-process state. | |
| EXPOSE 7860 | |
| CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"] | |