# syntax=docker/dockerfile:1
#
# Dev image for the backend: source is mounted, `air` rebuilds and restarts on
# save. Paired with the go-mod and build caches as named volumes in
# docker-compose.dev.yml, a save-to-running-server goes from ~110s (full
# image rebuild: go mod download + go build from cold) to a few seconds.
#
# The production image in ../Dockerfile is untouched. Nothing here changes how
# the service is deployed, only how fast the edit loop is.
# Tag tracks what go.mod requires (go 1.26.5) and matches the image the test
# runs use. Pinning a lower minor here fails the build outright with
# "go.mod requires go >= 1.26.5", which is a wasted build cycle to discover.
FROM golang:alpine

RUN apk add --no-cache git build-base
# air is installed at build time so a code change never pays for a toolchain
# download, and so the version is pinned by the image rather than by whatever
# `go install` resolves today.
RUN go install github.com/air-verse/air@v1.61.5

WORKDIR /src
# Module graph first: this layer is cached by Docker and only invalidated when
# go.mod/go.sum change, not on every source edit.
COPY go.mod go.sum ./
RUN go mod download

COPY . .

# Written to /src/.air so it stays with the mount and is gitignored there.
ENV AIR_WATCH="." \
    AIR_EXT="go" \
    AIR_EXCLUDE_DIR="vendor,data,deploy,node_modules" \
    AIR_BUILD_CMD="CGO_ENABLED=0 go build -o /tmp/server ./cmd/server" \
    AIR_FULL_BUILD=false \
    AIR_RUN_CMD="/tmp/server" \
    AIR_APP_PID=0 \
    AIR_RERUN=false \
    AIR_DELAY=200

EXPOSE 8080
# No HEALTHCHECK override: the real one would restart the container while a
# rebuild is in flight, which looks like a crash loop when it is only a build.
CMD ["air", "-c", ".air.toml"]
