# syntax=docker/dockerfile:1.7
#
# SCOPENET admin panel — a single static binary + the web UI on `scratch`.
# Multi-arch (amd64/arm64) is cross-compiled with cargo-zigbuild on the
# build machine's native arch, so no slow QEMU emulation is needed.

# ---- 1. Web UI ---------------------------------------------------------------
FROM --platform=$BUILDPLATFORM node:22-alpine AS web
WORKDIR /src/panel/web
COPY panel/web/package.json panel/web/package-lock.json ./
RUN npm ci --no-audit --no-fund
COPY panel/web/ ./
RUN npm run build

# ---- 2. Server binary --------------------------------------------------------
FROM --platform=$BUILDPLATFORM rust:1-slim-bookworm AS build
ARG TARGETARCH
# zig (via the cargo-zigbuild wheel) is the cross C toolchain for musl targets.
RUN apt-get update && apt-get install -y --no-install-recommends python3-pip \
 && rm -rf /var/lib/apt/lists/* \
 && pip install --no-cache-dir --break-system-packages cargo-zigbuild
RUN case "$TARGETARCH" in \
      amd64) echo x86_64-unknown-linux-musl ;; \
      arm64) echo aarch64-unknown-linux-musl ;; \
      *) echo "unsupported arch $TARGETARCH" >&2; exit 1 ;; \
    esac > /rust-target \
 && rustup target add "$(cat /rust-target)"
WORKDIR /src
COPY . .
# No --locked: release builds stamp the version into Cargo.toml. Dependencies
# stay pinned by Cargo.lock either way (CI enforces --locked).
RUN --mount=type=cache,target=/usr/local/cargo/registry,id=cargo-registry,sharing=locked \
    --mount=type=cache,target=/src/target,id=scopenet-target-$TARGETARCH \
    cargo zigbuild --release -p scopenet-panel --target "$(cat /rust-target)" \
 && cp "target/$(cat /rust-target)/release/scopenet-panel" /scopenet-panel
# Data dir owned by the non-root runtime user.
RUN mkdir -p /out/data && chown 65532:65532 /out/data

# ---- 3. Runtime --------------------------------------------------------------
FROM scratch
LABEL org.opencontainers.image.title="SCOPENET Panel" \
      org.opencontainers.image.description="Admin panel for the SCOPENET Minecraft launcher" \
      org.opencontainers.image.source="https://github.com/scopeddlol/SCOPENET-MC"
COPY --from=build /scopenet-panel /scopenet-panel
COPY --from=web /src/panel/web/dist /web
COPY --from=build --chown=65532:65532 /out/data /data
ENV SCOPENET_BIND=0.0.0.0:8080 \
    SCOPENET_DATA_DIR=/data \
    SCOPENET_WEB_DIR=/web \
    RUST_LOG=info
USER 65532:65532
VOLUME ["/data"]
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 CMD ["/scopenet-panel", "healthcheck"]
ENTRYPOINT ["/scopenet-panel"]
