# syntax=docker/dockerfile:1
#
# Two build stages that do not know about each other — the Go binary and the
# Vite bundle — collapsed into one small runtime image. The server serves both
# the API and the built frontend, so there is a single process to run and a
# single port to expose.

# ------------------------------------------------------------------ web ----
FROM node:24-alpine AS web
RUN corepack enable
WORKDIR /web
COPY web/package.json web/pnpm-lock.yaml web/pnpm-workspace.yaml ./
RUN pnpm install --frozen-lockfile
COPY web/ ./
# The manifest this produces is what the Go server reads to find the hashed
# entry files, so a build without it would boot to an error.
RUN pnpm build

# ------------------------------------------------------------------ api ----
FROM golang:1.25-alpine AS api
WORKDIR /src
COPY api/go.mod api/go.sum ./
RUN go mod download
COPY api/ ./
# Static binary: the runtime image has no libc to link against.
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o /out/server ./cmd/server

# -------------------------------------------------------------- runtime ----
FROM alpine:3.22 AS runner
# curl is here for the healthcheck; the binary itself needs nothing but certs.
RUN apk add --no-cache ca-certificates curl \
 && addgroup -S app -g 1001 && adduser -S app -u 1001
WORKDIR /app

COPY --from=api /out/server /usr/local/bin/
COPY --from=web --chown=app:app /web/dist ./web

ENV ADDR=:3000 WEB_DIR=/app/web
USER app
EXPOSE 3000

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD curl -fsS http://127.0.0.1:3000/api/health || exit 1

CMD ["server"]

# ---------------------------------------------------------------- seeder ----
# The fixture loader, for development and CI only. Its first act is to DELETE
# every campaign, organisation and user, so it must not be reachable from the
# image that runs in production: `--target runner` never builds these two
# stages, and nothing in compose references them.
FROM api AS seedbuild
RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -ldflags="-s -w" -o /out/seed ./test/seed

FROM runner AS seeder
COPY --from=seedbuild /out/seed /usr/local/bin/
USER app
CMD ["seed"]
