# 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"]