# Build stage.
#
# CGO stays off: the SQLite driver is pure Go, so the result is a static binary
# that runs on any base image, including scratch.
FROM golang:1.26-alpine AS build

WORKDIR /src

# Dependencies first, so a source-only change reuses this layer.
COPY go.mod go.sum ./
RUN go mod download

COPY . .

ARG VERSION=dev
ARG COMMIT=unknown
ARG BUILD_DATE=unknown

RUN CGO_ENABLED=0 GOOS=linux go build \
    -trimpath \
    -ldflags="-s -w \
      -X github.com/owen/vibedns/internal/version.Version=${VERSION} \
      -X github.com/owen/vibedns/internal/version.Commit=${COMMIT} \
      -X github.com/owen/vibedns/internal/version.BuildDate=${BUILD_DATE}" \
    -o /out/vibedns ./cmd/vibedns

# Verify the templates and assets really are embedded, so a broken build fails
# here rather than at the first page load in production.
RUN CGO_ENABLED=0 go test ./internal/web/ -run TestStaticAssetsEmbedded -count=1


# Runtime stage.
FROM alpine:3.20

# ca-certificates is not needed for DNS itself, but keeps outbound HTTPS working
# if an operator ever fetches a blocklist from the host. tzdata makes log
# timestamps and retention windows follow the configured timezone.
RUN apk add --no-cache ca-certificates tzdata \
    && addgroup -g 10001 -S vibedns \
    && adduser -u 10001 -S -G vibedns -h /var/lib/vibedns vibedns \
    && mkdir -p /var/lib/vibedns \
    && chown -R vibedns:vibedns /var/lib/vibedns

COPY --from=build /out/vibedns /usr/local/bin/vibedns

# Allow binding port 53 as an unprivileged user. Without this the container
# would have to run as root just to open the DNS socket.
RUN apk add --no-cache libcap \
    && setcap 'cap_net_bind_service=+ep' /usr/local/bin/vibedns \
    && apk del libcap

USER vibedns
WORKDIR /var/lib/vibedns

VOLUME ["/var/lib/vibedns"]

EXPOSE 53/udp 53/tcp 8080/tcp

ENV VIBEDNS_DB_PATH=/var/lib/vibedns/dns.db \
    VIBEDNS_HTTP_ADDR=0.0.0.0:8080 \
    VIBEDNS_DNS_ADDR=0.0.0.0:53

# /healthz never touches the database, so a database problem does not cause the
# orchestrator to kill a process that is still answering from cache and zones.
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
    CMD wget -qO- http://127.0.0.1:8080/healthz >/dev/null || exit 1

ENTRYPOINT ["/usr/local/bin/vibedns"]
CMD ["serve"]
