# Multi-stage, multi-arch build for record-asr. # # docker build -t record-asr . # docker buildx build --platform linux/amd64,linux/arm64 -t record-asr:latest --push . # # buildx builds each platform NATIVELY (the builder image matches the target # arch), so cgo links the correct prebuilt .so for that arch and NO cross # compiler is needed — unlike the bare `make build-arm64` path. # ---- builder ---- FROM golang:1.22-bookworm AS builder WORKDIR /src # Allow overriding the Go module proxy, e.g. for restricted networks: # docker build --build-arg GOPROXY=https://goproxy.cn,direct -t record-asr . ARG GOPROXY=https://proxy.golang.org,direct ENV GOPROXY=${GOPROXY} # Cache module downloads (incl. the large sherpa-onnx-go .so) separately from # source so code changes don't re-download deps. COPY go.mod go.sum ./ RUN go mod download COPY . . # Build, then copy the prebuilt .so that match THIS builder's arch into /out/lib. # The glob avoids hard-coding the sherpa-onnx-go-linux version. RUN set -eux; \ CGO_ENABLED=1 go build -trimpath -o /out/record-asr .; \ arch="$(go env GOARCH)"; \ case "$arch" in \ amd64) libd=x86_64-unknown-linux-gnu;; \ arm64) libd=aarch64-unknown-linux-gnu;; \ *) echo "unsupported arch: $arch" >&2; exit 1;; \ esac; \ mkdir -p /out/lib; \ cp "$(go env GOMODCACHE)/github.com/k2-fsa/sherpa-onnx-go-linux@"*/lib/"$libd"/*.so /out/lib/ # ---- models: download SenseVoice int8 + silero VAD at BUILD time ---- # These are arch-independent ONNX files, so the same download serves every # platform. Baking them into the image means the container starts instantly # and needs no network at runtime. (One-time ~230MB cost per build.) FROM debian:bookworm-slim AS models RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates curl bzip2 \ && rm -rf /var/lib/apt/lists/* # Extract ONLY model.int8.onnx + tokens.txt from the release tarball (skip the # test wavs / float model) to keep the layer lean. --strip-components=1 flattens # the top archive dir so files land directly in /models/sensevoice/. RUN mkdir -p /models/sensevoice \ && curl -fsSL -o /tmp/sv.tar.bz2 \ "https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-sense-voice-zh-en-ja-ko-yue-int8-2024-07-17.tar.bz2" \ && tar -xjf /tmp/sv.tar.bz2 -C /models/sensevoice \ --strip-components=1 --wildcards --no-anchored 'model.int8.onnx' 'tokens.txt' \ && rm -f /tmp/sv.tar.bz2 \ && curl -fsSL -o /models/silero_vad.onnx \ "https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/silero_vad.onnx" \ && test -s /models/sensevoice/model.int8.onnx \ && test -s /models/sensevoice/tokens.txt \ && test -s /models/silero_vad.onnx \ && ls -lh /models/sensevoice /models/silero_vad.onnx # ---- runtime (glibc; sherpa-onnx .so are glibc-built, so NOT alpine/musl) ---- FROM debian:bookworm-slim # APT_MIRROR: optionally swap deb.debian.org for a faster regional mirror, e.g. # docker build --build-arg APT_MIRROR=mirrors.tuna.tsinghua.edu.cn -t record-asr . # Defaults to the upstream deb.debian.org (no swap). ffmpeg (~250MB of codec # libs) decodes m4a/aac/opus/wma — beep is pure-Go for wav/mp3/flac/ogg only. ARG APT_MIRROR= RUN set -eux; \ if [ -n "$APT_MIRROR" ]; then \ f=/etc/apt/sources.list.d/debian.sources; \ if [ -f "$f" ]; then sed -i "s|deb.debian.org|$APT_MIRROR|g; s|security.debian.org|$APT_MIRROR|g" "$f"; \ else sed -i "s|deb.debian.org|$APT_MIRROR|g; s|security.debian.org|$APT_MIRROR|g" /etc/apt/sources.list; fi; \ fi; \ apt-get update \ && apt-get install -y --no-install-recommends ca-certificates curl ffmpeg \ && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY --from=builder /out/record-asr /app/record-asr COPY --from=builder /out/lib /app/lib COPY --from=models /models /models # Defaults; override via -e / compose. Models are baked in at /models, so # startup skips the download entirely. Only /app/data (tasks + uploads) is a # volume; it never holds models. ENV ASR_ADDR=:8080 \ ASR_DATA_DIR=/app/data \ ASR_MODEL_DIR=/models \ ASR_DOWNLOAD_TIMEOUT=1800 \ LD_LIBRARY_PATH=/app/lib VOLUME /app/data EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \ CMD curl -fsS http://127.0.0.1:8080/healthz || exit 1 ENTRYPOINT ["/app/record-asr"]