Files
next.js/scripts/native-builder.Dockerfile
T
Matt MastracciandGitHub 3e847dfe0b Switch to cargo-binstall and pre-built sccache binaries (#92911)
## What

- Use `cargo binstall` instead of `cargo install` for Rust tools in the
Docker image
- Download pre-built vercel/sccache from GitHub releases instead of
compiling from git

## Why

`cargo install` compiles from source which is slow on cache miss. `cargo
binstall` downloads pre-built binaries in seconds. The vercel/sccache
fork now publishes release binaries, eliminating the need for the
`build-sccache` turbo task (~2-3 min compile).

## Changes

**Dockerfile:**
- Install cargo-binstall at pinned version (1.18.1), use it for
cargo-rustflags
- Remove sccache from Docker image (not needed inside container)

**CI sccache:**
- Download pre-built binary from `vercel/sccache` GitHub releases
(~11MB)
- Cache in `~/.cache/sccache-<version>` on self-hosted runners
- Delete `scripts/build-sccache.js`, remove turbo task and package.json
entry
- `scripts/sccache-version` now contains just the release tag

<!-- NEXT_JS_LLM_PR -->
2026-04-17 17:09:11 +00:00

99 lines
4.7 KiB
Docker
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Multi-stage Dockerfile for building Next.js native binaries (next-swc).
#
# Produces a single image that can cross-compile ALL 4 Linux targets
# (x86_64/aarch64 × gnu/musl) from either an x86_64 or aarch64 host.
#
# Build:
# docker build -t next-swc-builder:latest -f scripts/native-builder.Dockerfile .
#
# The image includes:
# - Ubuntu 20.04 (glibc 2.31 — broad compatibility baseline)
# - Clang/LLD for all compilation and linking via --target
# - GNU cross-sysroots via crossbuild-essential (Ubuntu multiarch)
# - musl sysroots from musl.cc (headers + libs only; clang/lld do the work)
# - Node.js 20 (glibc-linked, used as build tool for all targets)
# - Rust nightly toolchain (pinned to match rust-toolchain.toml)
# - @napi-rs/cli for building native Node.js addons
FROM ubuntu:20.04 AS builder
# Avoid interactive prompts during apt-get
ENV DEBIAN_FRONTEND=noninteractive
# Enable multiarch for cross-compilation sysroots.
# Write sources.list from scratch with explicit [arch=...] tags.
# On arm64 hosts: native packages from ports, foreign amd64 from archive.
# On amd64 hosts: native packages from archive, foreign arm64 from ports.
RUN HOST_ARCH=$(dpkg --print-architecture) && \
if [ "$HOST_ARCH" = "arm64" ]; then \
NATIVE_MIRROR="http://ports.ubuntu.com/ubuntu-ports"; FOREIGN_ARCH=amd64; \
FOREIGN_MIRROR="http://archive.ubuntu.com/ubuntu"; \
else \
NATIVE_MIRROR="http://archive.ubuntu.com/ubuntu"; FOREIGN_ARCH=arm64; \
FOREIGN_MIRROR="http://ports.ubuntu.com/ubuntu-ports"; \
fi && \
dpkg --add-architecture "$FOREIGN_ARCH" && \
printf '%s\n' \
"deb [arch=${HOST_ARCH}] ${NATIVE_MIRROR} focal main universe" \
"deb [arch=${HOST_ARCH}] ${NATIVE_MIRROR} focal-updates main universe" \
"deb [arch=${HOST_ARCH}] ${NATIVE_MIRROR} focal-security main universe" \
"deb [arch=${FOREIGN_ARCH}] ${FOREIGN_MIRROR} focal main universe" \
"deb [arch=${FOREIGN_ARCH}] ${FOREIGN_MIRROR} focal-updates main universe" \
"deb [arch=${FOREIGN_ARCH}] ${FOREIGN_MIRROR} focal-security main universe" \
> /etc/apt/sources.list
# Core build tools + GNU cross-compilation sysroots + Node.js 20 via nodesource.
# crossbuild-essential installs headers + libs in the multiarch layout
# that clang finds via --target. Both archs installed so the image
# works on either host architecture.
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates && \
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get install -y --no-install-recommends \
nodejs \
clang lld llvm pkg-config wget git xz-utils libssl-dev \
crossbuild-essential-amd64 crossbuild-essential-arm64 \
&& rm -rf /var/lib/apt/lists/*
# Download musl cross-toolchains from musl.cc for their sysroots
# (headers, crt files, libc, libgcc). Clang + rust-lld handle compilation
# and linking; we only need the target libraries.
# Also copy GCC's crt files and libgcc into the sysroot lib dir — clang 10
# doesn't search the --gcc-toolchain path for these files.
# https://musl.cc/
RUN cd /opt && \
for TRIPLE in aarch64-linux-musl x86_64-linux-musl; do \
wget -qO- "https://musl.cc/${TRIPLE}-cross.tgz" | tar xz && \
cp /opt/${TRIPLE}-cross/lib/gcc/${TRIPLE}/*/crt*.o \
/opt/${TRIPLE}-cross/lib/gcc/${TRIPLE}/*/libgcc.a \
/opt/${TRIPLE}-cross/${TRIPLE}/lib/; \
done
# Install Rust — pinned nightly from rust-toolchain.toml
# The COPY of rust-toolchain.toml ensures the image rebuilds when the toolchain changes.
COPY rust-toolchain.toml /tmp/rust-toolchain.toml
RUN TOOLCHAIN=$(grep 'channel' /tmp/rust-toolchain.toml | sed 's/.*"\(.*\)".*/\1/') && \
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
sh -s -- -y --default-toolchain "$TOOLCHAIN" --profile minimal && \
rm /tmp/rust-toolchain.toml
ENV PATH="/root/.cargo/bin:${PATH}"
# Add all 4 Linux rustup targets
RUN rustup target add \
x86_64-unknown-linux-gnu \
aarch64-unknown-linux-gnu \
x86_64-unknown-linux-musl \
aarch64-unknown-linux-musl
# Install cargo-binstall, then use it for Rust tools.
ARG CARGO_BINSTALL_VERSION=1.18.1
RUN ARCH=$(uname -m) && \
curl -fsSL "https://github.com/cargo-bins/cargo-binstall/releases/download/v${CARGO_BINSTALL_VERSION}/cargo-binstall-${ARCH}-unknown-linux-musl.tgz" \
| tar xz -C /root/.cargo/bin && \
npm i -g @napi-rs/[email protected] && \
cargo binstall --no-confirm --targets "${ARCH}-unknown-linux-musl" [email protected] && \
cargo binstall --no-confirm --git https://github.com/vercel/sccache sccache && \
node --version && rustc --version && napi -h > /dev/null && cargo rustflags --help > /dev/null && sccache --version
WORKDIR /build