# ---- build ---- # Keep this in step with go.mod's `go` directive when it bumps. FROM golang:1.25-alpine AS build WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . # Pure-Go SQLite (modernc) means we can build a fully static binary with no cgo. RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /lchat . # Staged here so the runtime image (which has no shell to mkdir with) can copy # in a /data already owned by nonroot — a named volume then inherits writable # ownership on first use. A bind mount still needs a host-side chown to 65532. RUN mkdir -p /data # ---- run ---- # distroless/static:nonroot: ~2MB, no shell, runs as uid 65532 — the container # never needs root. The frontend and SQLite engine are embedded in /lchat. FROM gcr.io/distroless/static-debian12:nonroot COPY --from=build --chown=nonroot:nonroot /data /data COPY --from=build /lchat /lchat # Runtime config comes from env: LCHAT_DB (point it at /data), ADDR, # LCHAT_ADMIN_TOKEN. See README.md § Docker. EXPOSE 1747 VOLUME /data ENTRYPOINT ["/lchat"]