From 425b1d45d69728b6f69a94bb96b9b0be0b97975c Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Mon, 27 Apr 2026 22:57:09 -0700 Subject: [PATCH] =?UTF-8?q?stacks/fish-s2:=20build=20from=20docker/Dockerf?= =?UTF-8?q?ile=20(not=20dockerfile.dev)=20=E2=80=94=20third=20try?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Second deploy attempt failed at build time: failed to fetch anonymous token: ... ghcr.io/fishaudio/fish-speech ... 403 Forbidden Root cause: dockerfile.dev is a thin two-line wrapper around `FROM ghcr.io/fishaudio/fish-speech:${VERSION}`, which is a private GHCR base image. Anonymous pulls 403, and we'd need GHCR auth to use that path. The dev variant is meant for upstream's CI / fish-speech contributors, not external consumers. The REAL production path (from upstream's compose.base.yml) is to build from `docker/Dockerfile` with build args BACKEND=cuda, CUDA_VER=12.9.0, UV_EXTRA=cu129, UV_VERSION=0.8.15. That builds everything from source — slower (15-20 min cold), but fully self- contained. irv-ml1's driver (595.58.03, CUDA 13.2 capable) is forward-compatible with the 12.9 PyTorch wheels. Took three iterations to find the right Dockerfile because: 1. First try: dockerfile (lowercase) — doesn't exist 2. Second try: dockerfile.dev — exists but pulls a private base 3. Third try: docker/Dockerfile — actual production path --- stacks/fish-s2/compose.yaml | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/stacks/fish-s2/compose.yaml b/stacks/fish-s2/compose.yaml index 450104f..04167cf 100644 --- a/stacks/fish-s2/compose.yaml +++ b/stacks/fish-s2/compose.yaml @@ -26,18 +26,23 @@ services: image: local/fish-s2:${FISH_S2_TAG} build: context: https://github.com/fishaudio/fish-speech.git#${FISH_S2_SHA} - # Upstream ships `dockerfile.dev` (lowercase, dev/test image) - # rather than a plain Dockerfile — there is no production - # Dockerfile. Their intended path is `docker compose --profile - # server up` against their own compose.yml; we use the same - # underlying dockerfile.dev image but layer our own compose on - # top so it slots into our fleet conventions (restart, labels, - # bind mounts, healthcheck). - dockerfile: dockerfile.dev + # The REAL production Dockerfile is at docker/Dockerfile (per + # upstream's compose.base.yml). The repo also ships a + # `dockerfile.dev` at root which is a thin + # `FROM ghcr.io/fishaudio/fish-speech:${VERSION}` wrapper meant + # for dev iteration on top of a private base image — that path + # 403s on anonymous pulls. Build from source via docker/Dockerfile + # instead. + dockerfile: docker/Dockerfile args: - # Upstream's dockerfile.dev reads BACKEND to choose CUDA vs CPU - # paths during pip install. We always want CUDA on irv-ml1. + # Build args mirror upstream compose.base.yml defaults. + # CUDA_VER 12.9 + UV_EXTRA cu129 = the CUDA 12.9 PyTorch wheels. + # irv-ml1's driver (595.58.03 / CUDA 13.2 capable) is + # backward-compatible with 12.9-built images. BACKEND: cuda + CUDA_VER: "12.9.0" + UV_EXTRA: cu129 + UV_VERSION: "0.8.15" container_name: fish-s2 restart: unless-stopped runtime: nvidia