# Multi-stage build for the backend service. Mirrors platform/telegram/Dockerfile: # a golang-alpine builder yields a static binary shipped on distroless nonroot. # # The dictionary DAWGs are baked in from the scrabble-dictionary release artifact # โ€” the same set the Go CI downloads โ€” and BACKEND_DICT_DIR points the # binary at them. The published solver module is fetched directly from Gitea # (GOPRIVATE), so the build stage needs git and network. # # Build from the repository root so go.work, go.work.sum, pkg/ and backend/ are all # in the Docker context: # docker build -f backend/Dockerfile -t scrabble-backend . # --- dictionary artifact ----------------------------------------------------- FROM alpine:3.20 AS dawg ARG DICT_VERSION=v1.3.0 RUN apk add --no-cache curl tar RUN mkdir -p /dawg \ && curl -fsSL -o /tmp/dawg.tar.gz \ "https://gitea.iliadenisov.ru/developer/scrabble-dictionary/releases/download/${DICT_VERSION}/scrabble-dawg-${DICT_VERSION}.tar.gz" \ && tar xzf /tmp/dawg.tar.gz -C /dawg # --- build ------------------------------------------------------------------- FROM golang:1.26.3-alpine AS build WORKDIR /src # git: the published solver module is fetched from Gitea directly (GOPRIVATE). RUN apk add --no-cache git ENV GOPRIVATE=gitea.iliadenisov.ru/* COPY go.work go.work.sum ./ COPY pkg ./pkg COPY backend ./backend # Reduce the workspace to what the backend needs: backend + pkg. loadtest and the # gateway replace it requires are not in this context, so drop both. RUN go work edit -dropuse=./gateway -dropuse=./platform/telegram -dropuse=./loadtest -dropreplace=scrabble/gateway@v0.0.0 # VERSION (the deploy passes the git tag) is stamped into the binary via the linker. ARG VERSION=dev RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags "-X scrabble/pkg/version.Version=${VERSION}" -o /out/backend ./backend/cmd/backend # --- runtime ----------------------------------------------------------------- FROM gcr.io/distroless/static-debian12:nonroot # Re-declare the build arg in this stage so it labels the seed dictionary. One # DICT_VERSION drives both the artifact the dawg stage downloads and the version # label the binary pins, so the resident version equals the release tag. ARG DICT_VERSION=v1.3.0 COPY --from=build /out/backend /usr/local/bin/backend # Own the seed dictionary as the nonroot runtime user (UID 65532): a named volume # mounted at /opt/dawg inherits this ownership on first use, so the admin console # can write new version subdirectories at runtime. The volume preserves uploaded # versions across deploys and, once seeded, is not re-seeded โ€” so after bootstrap # every dictionary change goes through the console, not a rebuild (ARCHITECTURE.md ยง5). COPY --from=dawg --chown=65532:65532 /dawg /opt/dawg ENV BACKEND_DICT_DIR=/opt/dawg ENV BACKEND_DICT_VERSION=${DICT_VERSION} ENTRYPOINT ["/usr/local/bin/backend"]