-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
126 lines (101 loc) · 4.8 KB
/
Copy pathDockerfile
File metadata and controls
126 lines (101 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# syntax=docker/dockerfile:1.7@sha256:a57df69d0ea827fb7266491f2813635de6f17269be881f696fbfdf2d83dda33e
# Multi-stage rootless image for transcriptasm.
# Base digests pinned to multi-arch OCI indexes (Alpine 3.24 / Go 1.26-alpine).
ARG ALPINE_DIGEST=sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b
ARG GOLANG_DIGEST=sha256:ce864e7223ac17b1775e6fd0b4c0db580c2eb50e7953a427916379e4b92a1628
ARG VERSION=0.1.0
ARG REVISION=unknown
ARG CREATED=unknown
FROM golang:1.26-alpine@${GOLANG_DIGEST} AS builder
ARG VERSION
ARG TARGETOS
ARG TARGETARCH
WORKDIR /src
COPY go.mod ./
COPY cmd ./cmd
COPY internal ./internal
ENV CGO_ENABLED=0
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH:-amd64} \
go build \
-trimpath \
-buildvcs=false \
-ldflags="-s -w -X github.com/Quad4-Software/transcriptasm/internal/version.Version=${VERSION}" \
-o /out/transcriptasm \
./cmd/transcriptasm
FROM alpine:3.24@${ALPINE_DIGEST} AS models
RUN apk add --no-cache curl bash \
&& mkdir -p /models /onnx /transformers
# ggml WASM fallback weights
RUN curl -L --fail --retry 5 --retry-delay 2 \
-o /models/ggml-tiny.en-q5_1.bin \
"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en-q5_1.bin" \
&& curl -L --fail --retry 5 --retry-delay 2 \
-o /models/ggml-base.en-q5_1.bin \
"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en-q5_1.bin" \
&& curl -L --fail --retry 5 --retry-delay 2 \
-o /models/ggml-tiny-q5_1.bin \
"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny-q5_1.bin" \
&& curl -L --fail --retry 5 --retry-delay 2 \
-o /models/ggml-base-q5_1.bin \
"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base-q5_1.bin" \
&& curl -L --fail --retry 5 --retry-delay 2 \
-o /models/ggml-small.en-q5_1.bin \
"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.en-q5_1.bin"
# transformers.js + ORT for WebGPU
ARG TRANSFORMERS_JS_VERSION=3.7.2
RUN BASE="https://cdn.jsdelivr.net/npm/@huggingface/transformers@${TRANSFORMERS_JS_VERSION}/dist" \
&& curl -L --fail --retry 5 --retry-delay 2 -o /transformers/transformers.min.js "$BASE/transformers.min.js" \
&& curl -L --fail --retry 5 --retry-delay 2 -o /transformers/ort-wasm-simd-threaded.jsep.mjs "$BASE/ort-wasm-simd-threaded.jsep.mjs" \
&& curl -L --fail --retry 5 --retry-delay 2 -o /transformers/ort-wasm-simd-threaded.jsep.wasm "$BASE/ort-wasm-simd-threaded.jsep.wasm"
# ONNX hybrid models (fp32 encoder + q4 decoder)
COPY scripts/fetch-onnx-models.sh /tmp/fetch-onnx-models.sh
RUN chmod +x /tmp/fetch-onnx-models.sh \
&& ONNX_OUT=/onnx-models bash /tmp/fetch-onnx-models.sh
FROM alpine:3.24@${ALPINE_DIGEST} AS runtime
ARG VERSION
ARG REVISION
ARG CREATED
ARG ALPINE_DIGEST
ARG GOLANG_DIGEST
LABEL org.opencontainers.image.title="transcriptasm" \
org.opencontainers.image.description="Offline in-browser Whisper transcription via WebGPU and WASM" \
org.opencontainers.image.version="${VERSION}" \
org.opencontainers.image.revision="${REVISION}" \
org.opencontainers.image.created="${CREATED}" \
org.opencontainers.image.licenses="0BSD" \
org.opencontainers.image.vendor="transcriptasm" \
org.opencontainers.image.source="https://github.com/Quad4-Software/transcriptasm" \
org.opencontainers.image.url="https://transcriptasm.quad4.io" \
org.opencontainers.image.documentation="https://github.com/Quad4-Software/transcriptasm" \
org.opencontainers.image.base.name="docker.io/library/alpine:3.24" \
org.opencontainers.image.base.digest="${ALPINE_DIGEST}" \
org.opencontainers.image.ref.name="transcriptasm:${VERSION}"
RUN apk upgrade --no-cache \
&& addgroup -g 65532 -S nonroot \
&& adduser -u 65532 -S -D -H -G nonroot nonroot \
&& mkdir -p /app/web/models /app/web/vendor/transformers \
&& chown -R nonroot:nonroot /app
COPY --from=builder --chown=nonroot:nonroot /out/transcriptasm /app/transcriptasm
COPY --chown=nonroot:nonroot web /app/web
COPY --from=models --chown=nonroot:nonroot /models/ /app/web/models/
COPY --from=models --chown=nonroot:nonroot /onnx-models/ /app/web/models/onnx/
COPY --from=models --chown=nonroot:nonroot /transformers/ /app/web/vendor/transformers/
RUN test -f /app/web/vendor/whisper/main.js \
&& test -f /app/web/vendor/whisper/main.wasm \
&& test -f /app/web/models/ggml-tiny.en-q5_1.bin \
&& test -f /app/web/vendor/transformers/transformers.min.js \
&& chmod 0555 /app/transcriptasm \
&& chmod -R a-w /app/web
ENV TRANSCRIPTASM_ADDR=":8080" \
TRANSCRIPTASM_WEB="/app/web" \
HOME="/tmp"
WORKDIR /app
USER 65532:65532
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget -q -O /dev/null http://127.0.0.1:8080/api/health || exit 1
STOPSIGNAL SIGTERM
ENTRYPOINT ["/app/transcriptasm"]
CMD ["-addr", ":8080", "-web", "/app/web"]