73 lines
3.2 KiB
Docker
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"]
|