Files
dnswatcher/Dockerfile
clawbot 1ab0b9f61d
check / check (push) Successful in 59s
script: force lint and test to run in cibuild and docker (closes #115)
script/cibuild and script/docker were plain docker build. On an
unchanged tree the lint stage and the builder stage, which runs make
test, came from the layer cache, so the build passed without linting
or querying live DNS. Both scripts now pass
--no-cache-filter=lint,builder so those stages run on every build, as
script/lint already does for its own lint stage. Dependency downloads
inside those stages re-run each build. Each of the two stages in the
Dockerfile now notes that the scripts name it. README and TODO.md
updated to match.

Model: opus-4-8 (implementation); opus-5-5 (rework)
2026-09-28 23:13:38 +02:00

76 lines
2.6 KiB
Docker

# Lint stage - fast feedback on lint issues, before the build starts.
# The linter is invoked directly rather than through `make lint`: that
# target shells out to `docker build -f Dockerfile.lint`, and there is
# no docker daemon inside a docker build.
# script/cibuild and script/docker name this stage in --no-cache-filter.
# golangci/golangci-lint:v2.12.2 (Debian-based), 2026-08-10
FROM golangci/golangci-lint:v2.12.2@sha256:5cceeef04e53efe1470638d4b4b4f5ceefd574955ab3941b2d9a68a8c9ad5240 AS lint
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN make fmt-check
RUN golangci-lint run --config .golangci.yml ./...
# Build stage
# script/cibuild and script/docker name this stage in --no-cache-filter.
# golang 1.25-alpine, 2026-02-28
FROM golang@sha256:f6751d823c26342f9506c03797d2527668d095b0a15f1862cddb4d927a7a4ced AS builder
RUN apk add --no-cache git make gcc musl-dev binutils-gold
# Force BuildKit to run the lint stage before proceeding
COPY --from=lint /src/go.sum /dev/null
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# Run the tests - build fails if any test fails
RUN make test
# Build the binary
RUN make build
# Runtime stage
# alpine 3.21, 2026-02-28
FROM alpine@sha256:c3f8e73fdb79deaebaa2037150150191b9dcbfba68b4a46d70103204c53f4709
RUN apk add --no-cache ca-certificates tzdata
COPY --from=builder /src/bin/dnswatcher /usr/local/bin/dnswatcher
# Run as an unprivileged user that owns the data directory. A fresh named
# volume inherits this ownership; a bind-mounted host directory must be
# owned by uid 10001 (see "Running under upaas" in README.md), or startup
# fails.
RUN addgroup -S -g 10001 dnswatcher \
&& adduser -S -G dnswatcher -u 10001 dnswatcher \
&& mkdir -p /var/lib/dnswatcher \
&& chown dnswatcher:dnswatcher /var/lib/dnswatcher
ENV DNSWATCHER_DATA_DIR=/var/lib/dnswatcher
# Config loading also reads a `.env` file and a file named `dnswatcher`
# (any config extension, or none) from the working directory. `/` holds
# neither, so every setting comes from the environment. Do not make the
# data directory, or the binary's directory, the working directory.
WORKDIR /
USER dnswatcher
EXPOSE 8080
# busybox wget (already in alpine) probes the health endpoint every 10
# seconds, so the container is healthy well before upaas reads its health
# 60 seconds after a deploy and fails the deploy unless it is healthy.
HEALTHCHECK --interval=10s --timeout=5s --start-period=10s --retries=3 \
CMD wget -q -O /dev/null "http://127.0.0.1:${PORT:-8080}/.well-known/healthcheck" || exit 1
ENTRYPOINT ["/usr/local/bin/dnswatcher"]