# syntax=docker/dockerfile:1

# --- Build stage -------------------------------------------------------
# golang:1.26 matches the "go 1.26.0" directive in go.mod (GOTOOLCHAIN=auto
# would otherwise re-download the right toolchain anyway, but pinning here
# keeps builds hermetic and fast).
FROM golang:1.26-alpine AS builder

WORKDIR /src

# Cache deps in their own layer.
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
    go mod download

COPY . .

# CGO disabled -> static binary, runs on the scratch-ish alpine base below
# with no libc surprises. Both entrypoints are built from the same module:
# cmd/api is the long-running server, cmd/seed is the one-shot admin
# bootstrap job (see charts/backend/templates/seed-job.yaml).
RUN --mount=type=cache,target=/go/pkg/mod \
    --mount=type=cache,target=/root/.cache/go-build \
    CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o /out/api ./cmd/api && \
    CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o /out/seed ./cmd/seed

# --- Runtime stage -------------------------------------------------------
FROM alpine:3.20

RUN apk add --no-cache ca-certificates tzdata && \
    addgroup -S app && adduser -S app -G app

WORKDIR /app

COPY --from=builder /out/api /out/seed ./
# Migrations are baked into the image so the migration Job (see
# charts/backend/templates/migration-job.yaml) always runs the set that
# matches the running server, without needing a separate artifact.
COPY --from=builder /src/migrations ./migrations

# Local-disk media storage (MEDIA_STORAGE_DRIVER=local) writes here; the
# chart mounts a PVC at this path when persistence is enabled. Owned by the
# non-root "app" user created above.
RUN mkdir -p /app/uploads /app/verification-uploads && \
    chown -R app:app /app

USER app
EXPOSE 8080

ENTRYPOINT ["/app/api"]
