Files

73 lines
3.2 KiB
Docker

# The binary is NOT compiled here. Build it first, from the repository root:
#
# (cd web && npm ci && npm run build)
# zig build dist -Dversion-string=<V> -Dgit-commit=<SHA> \
# -Dweb-dist=web/dist -Doptimize=ReleaseSafe
#
# then build the image with the repository root as context:
#
# docker build -t nxdns -f deploy/docker/Dockerfile .
#
# The builder stage only copies files, so it is pinned to $BUILDPLATFORM: the
# arm64 image is assembled natively and needs no qemu under buildx. That makes
# BuildKit a requirement, not a preference. `DOCKER_BUILDKIT=0` fails at the
# first FROM, because the classic builder defines no BUILDPLATFORM and rejects
# the empty `--platform=`. Do not "fix" that by declaring
# `ARG BUILDPLATFORM=<default>`: a declared default shadows BuildKit's built-in
# and silently drags the builder stage back under emulation on cross builds.
#
# It stages the CA bundle that the pinned base already ships (upstream DoH/DoT
# verification rescans the system store; a scratch image without one breaks
# every TLS upstream) and maps TARGETARCH onto the zig target triple. A builder
# that leaves TARGETARCH empty falls back to the build host's `uname -m`: no
# build may package a foreign binary that only fails at `docker run` with
# exec-format.
FROM --platform=$BUILDPLATFORM alpine:3.22@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce AS builder
ARG TARGETARCH
COPY zig-out/dist/bin /dist/bin
COPY zig-out/dist/stage /dist/stage
RUN set -eu; \
mkdir -p /rootfs/etc/ssl/certs /rootfs/etc/nxdns /rootfs/var/lib/nxdns; \
cp /etc/ssl/certs/ca-certificates.crt /rootfs/etc/ssl/certs/; \
arch="${TARGETARCH:-}"; \
if [ -z "$arch" ]; then \
case "$(uname -m)" in \
x86_64) arch=amd64 ;; \
aarch64) arch=arm64 ;; \
*) echo "unsupported build host $(uname -m); use buildx" >&2; exit 1 ;; \
esac; \
fi; \
case "$arch" in \
amd64) triple=x86_64-linux-musl ;; \
arm64) triple=aarch64-linux-musl ;; \
*) echo "unsupported TARGETARCH '${TARGETARCH}'" >&2; exit 1 ;; \
esac; \
cp "/dist/bin/$triple/nxdns" /rootfs/nxdns; \
chmod 0755 /rootfs/nxdns; \
stage=$(find /dist/stage -mindepth 1 -maxdepth 1 -type d -name "nxdns-*-$triple"); \
if [ "$(printf '%s' "$stage" | grep -c '^')" != 1 ]; then \
echo "expected exactly one /dist/stage dir for $triple, found: $stage" >&2; exit 1; \
fi; \
cp "$stage/LICENSE" "$stage/THIRD-PARTY-NOTICES" /rootfs/; \
chmod 0644 /rootfs/LICENSE /rootfs/THIRD-PARTY-NOTICES; \
chown 65532:65532 /rootfs/var/lib/nxdns
FROM scratch
ARG VERSION=0.0.0-dev
ARG REVISION=unknown
ARG CREATED=1970-01-01T00:00:00Z
LABEL org.opencontainers.image.source="https://git.mial.net/mokhtar/nxdns" \
org.opencontainers.image.revision="$REVISION" \
org.opencontainers.image.version="$VERSION" \
org.opencontainers.image.licenses="EUPL-1.2" \
org.opencontainers.image.created="$CREATED" \
org.opencontainers.image.title="nxdns" \
org.opencontainers.image.description="Self-hosted DNS sinkhole for a household LAN"
COPY --from=builder /rootfs/ /
USER 65532:65532
VOLUME /var/lib/nxdns
EXPOSE 53/udp 53/tcp 8080 443 853
ENTRYPOINT ["/nxdns"]
CMD ["run"]