# Lint stage — fast feedback on formatting and lint issues. The # golangci/golangci-lint image ships Go, gofmt, make and the linter, so # nothing is installed here. # golangci/golangci-lint:v2.7.2 (2026-08-09) FROM golangci/golangci-lint@sha256:5d6d5c70a61f1356adfd9dd6316ce286799fefc9d743421356ff1b00842368ba AS lint WORKDIR /src COPY backend/go.mod backend/go.sum ./ RUN go mod download COPY backend/ . RUN make fmt-check RUN make lint # Build stage # golang:1.25-alpine (2026-02-27) FROM golang:1.25-alpine@sha256:f6751d823c26342f9506c03797d2527668d095b0a15f1862cddb4d927a7a4ced AS builder RUN apk add --no-cache make WORKDIR /src # Force BuildKit to run the lint stage before proceeding. BuildKit runs # stages in parallel by default; without this no-op copy a lint failure # would not gate compilation. COPY --from=lint /src/go.sum /dev/null COPY backend/go.mod backend/go.sum ./ RUN go mod download COPY backend/ . RUN make test # The build is driven through the Makefile so there is exactly one # definition of the build command; it expands to # CGO_ENABLED=0 go build -trimpath -ldflags "-s -w -X main.Version=... -X main.Buildarch=..." # VERSION is handed over in the environment rather than as a make # variable so it still reaches the build if the target is ever turned # into a shim around a script. ARG VERSION=dev RUN VERSION="${VERSION}" make build # Runtime stage # alpine:3.23 (2026-02-27) FROM alpine:3.23@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 RUN apk add --no-cache ca-certificates COPY --from=builder /src/netwatch-server /usr/local/bin/netwatch-server EXPOSE 8080 ENTRYPOINT ["netwatch-server"]