# syntax=docker/dockerfile:1.6 # # Multi-stage, multi-arch build for vpp-maglev container images. # # Produces two runtime images from a single Alpine-based builder: # --target maglevd -> git.ipng.ch/ipng/vpp-maglevd:latest # --target frontend -> git.ipng.ch/ipng/vpp-maglevd-frontend:latest # # The builder stage runs on the host's native arch ($BUILDPLATFORM) and # Go cross-compiles to the image's target arch ($TARGETARCH), so a # single `docker buildx build --platform linux/amd64,linux/arm64` # produces a proper multi-arch manifest without a qemu-emulated # builder. Both BUILDPLATFORM and TARGETARCH are populated # automatically by buildx. # # Both images are driven by docker-compose.yaml at the repo root; see # README.md and .env.example. # ============================================================================= # Builder — compiles all four binaries against golang:alpine. # ============================================================================= FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS builder # TARGETARCH is supplied by buildx (amd64, arm64, ...). Declared here # so the make invocation below can reference it. ARG TARGETARCH # make drives the Go build; nodejs/npm are needed for the SolidJS SPA # that maglevd-frontend embeds at link time via //go:embed; git is used # by the Makefile's `git rev-parse --short HEAD` to stamp the commit # hash into the binary via -ldflags, and golang:alpine doesn't ship it. RUN apk add --no-cache make nodejs npm git WORKDIR /src # Cache Go modules first so code-only rebuilds skip the download. COPY go.mod go.sum ./ RUN go mod download COPY . . # The protoc-generated files are checked in, but docker COPY resets # their mtimes so make may think they need regenerating. Touch them # to ensure they are newer than the proto file and skip the rule. RUN touch internal/grpcapi/maglev.pb.go internal/grpcapi/maglev_grpc.pb.go # build-amd64 / build-arm64 both set GOOS=linux GOARCH= and emit # into build//, so the runtime stages below can COPY straight # out of build/$TARGETARCH/. CGO_ENABLED=0 is exported by the Makefile. RUN make build-$TARGETARCH # ============================================================================= # Runtime: maglevd (health-checker daemon) # ============================================================================= FROM alpine:3 AS maglevd ARG TARGETARCH # ca-certificates — HTTPS health checks need a trust store. # iproute2 — `ip netns` helpers, useful for debugging netns-scoped probes. RUN apk add --no-cache ca-certificates iproute2 COPY --from=builder /src/build/$TARGETARCH/maglevd /usr/sbin/maglevd # gRPC control plane (9090) and Prometheus /metrics (9091). The actual # listen addresses are set by MAGLEV_GRPC_ADDR / MAGLEV_METRICS_ADDR. EXPOSE 9090 9091 ENTRYPOINT ["/usr/sbin/maglevd"] # ============================================================================= # Runtime: maglevd-frontend (read-only dashboard + optional /admin/) # ============================================================================= FROM alpine:3 AS frontend ARG TARGETARCH RUN apk add --no-cache ca-certificates COPY --from=builder /src/build/$TARGETARCH/maglevd-frontend /usr/sbin/maglevd-frontend EXPOSE 8080 ENTRYPOINT ["/usr/sbin/maglevd-frontend"]