# syntax=docker/dockerfile:1 # --- Build stage ----------------------------------------------------------- FROM golang:1.26-alpine AS build WORKDIR /src # Download modules first so the layer caches unless go.mod/go.sum change. COPY go.mod go.sum ./ RUN go mod download COPY . . # Static, stripped binary. CGO is off so it runs on a scratch/distroless base. RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/dyzur-bot ./cmd/dyzur-bot # Writable cache dir, created here so it can be copied in with nonroot ownership. RUN mkdir /data # --- Runtime stage --------------------------------------------------------- # distroless static includes CA certificates (needed for HTTPS to Google) and # runs as the unprivileged "nonroot" user by default. Timezone data is embedded # in the binary via the time/tzdata import, so no system zoneinfo is required. FROM gcr.io/distroless/static:nonroot COPY --from=build /out/dyzur-bot /usr/local/bin/dyzur-bot # 65532 is the distroless "nonroot" uid/gid; use the numeric form so it resolves # without depending on /etc/passwd name lookup in the target image. COPY --from=build --chown=65532:65532 /data /data # Persist the rota cache to /data — mount a volume here to survive restarts. ENV ROTA_CACHE_PATH=/data/rota.json WORKDIR /data # Long polling: run EXACTLY ONE instance per bot token. Two concurrent pollers # get HTTP 409 Conflict from Telegram and drop updates. ENTRYPOINT ["/usr/local/bin/dyzur-bot"]