# JellyTau Builder Image # Pre-built image with all dependencies for building, testing, and packaging: # - Android APK (SDK/NDK), Linux desktop (deb/rpm), # - Windows cross via the official Tauri path: MSVC target + cargo-xwin + NSIS # Arch packages build in a separate archlinux image (Dockerfile.arch) since # makepkg is Arch-specific. # Push to your registry: docker build -f Dockerfile.builder -t gitea.tourolle.paris/dtourolle/jellytau-builder:latest . FROM ubuntu:24.04 ENV DEBIAN_FRONTEND=noninteractive \ ANDROID_HOME=/opt/android-sdk \ NDK_VERSION=27.0.11902837 \ SDK_VERSION=36 \ BUILD_TOOLS_VERSION=35.0.0 \ RUST_BACKTRACE=1 \ PATH="/root/.bun/bin:/root/.cargo/bin:$PATH" \ CARGO_HOME=/root/.cargo # Install system dependencies RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ curl \ wget \ git \ ca-certificates \ unzip \ jq \ openjdk-17-jdk-headless \ pkg-config \ libssl-dev \ libclang-dev \ llvm-dev \ # Tauri Linux desktop dependencies (needed for `cargo test` on the host target) libglib2.0-dev \ libgtk-3-dev \ libwebkit2gtk-4.1-dev \ libjavascriptcoregtk-4.1-dev \ libsoup-3.0-dev \ librsvg2-dev \ libayatana-appindicator3-dev \ # mpv player library (linked via libmpv-sys) libmpv-dev \ && rm -rf /var/lib/apt/lists/* # Install Node.js 20.x from NodeSource RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \ apt-get install -y --no-install-recommends nodejs && \ rm -rf /var/lib/apt/lists/* # Install Bun RUN curl -fsSL https://bun.sh/install | bash && \ ln -s /root/.bun/bin/bun /usr/local/bin/bun # Install Rust using rustup, pinned to an exact release. # # 🔴 RUST_VERSION must equal `channel` in src-tauri/rust-toolchain.toml. # # The two are a pair. rust-toolchain.toml is what makes a developer's `cargo # clippy` agree with CI's; this line is what makes the image already contain that # toolchain. If they drift, rustup silently downloads the pinned version the # first time cargo runs inside a job — a toolchain install at job time, which # CLAUDE.md's "🔴 CI installs no system tools" rule forbids (and which costs # ~1min plus a network dependency on every build). # # 🔴 Changing this line does NOT change CI on its own: the image must be # rebuilt and pushed (`scripts/build-builder-image.sh`) before the new pin is # authoritative. Bump rust-toolchain.toml and this line together, rebuild, push, # then merge. # # Was: `sh -s -- -y` (latest stable, whatever it happened to be on rebuild day). ENV RUST_VERSION=1.97.1 RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \ sh -s -- -y --profile minimal --default-toolchain "$RUST_VERSION" && \ . $HOME/.cargo/env && \ rustup default "$RUST_VERSION" && \ rustup target add aarch64-linux-android && \ rustup target add armv7-linux-androideabi && \ rustup target add x86_64-linux-android && \ rustup component add rustfmt clippy && \ rustc --version && \ cargo clippy --version # Setup Android SDK RUN mkdir -p $ANDROID_HOME && \ mkdir -p /root/.android && \ echo '### User Sources for `android` cmd line tool ###' > /root/.android/repositories.cfg && \ echo 'count=0' >> /root/.android/repositories.cfg # Download and setup Android Command Line Tools RUN wget -q https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip -O /tmp/cmdline-tools.zip && \ unzip -q /tmp/cmdline-tools.zip -d $ANDROID_HOME && \ rm /tmp/cmdline-tools.zip && \ mkdir -p $ANDROID_HOME/cmdline-tools/latest && \ mv $ANDROID_HOME/cmdline-tools/* $ANDROID_HOME/cmdline-tools/latest/ 2>/dev/null || true # Accept all SDK licenses up front so Gradle can install/use components non-interactively RUN yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --sdk_root=$ANDROID_HOME --licenses > /dev/null # Install Android SDK components (must match the compileSdk/targetSdk in the generated Gradle project) RUN $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --sdk_root=$ANDROID_HOME \ "platform-tools" \ "platforms;android-$SDK_VERSION" \ "build-tools;$BUILD_TOOLS_VERSION" \ "ndk;$NDK_VERSION" \ --channel=0 2>&1 | grep -v "Warning" || true # Set NDK environment variable ENV NDK_HOME=$ANDROID_HOME/ndk/$NDK_VERSION # Gradle distribution. `tauri android init` regenerates gen/android with a # wrapper pointing at services.gradle.org, so every Android job would otherwise # download ~130MB of Gradle at build time — slow, and a hard failure when the # CDN hiccups ("Unexpected end of file from server"). Ship the distribution in # the image instead; scripts/sync-android-sources.sh repoints the regenerated # wrapper at this local copy. Keep GRADLE_VERSION in sync with the version # Tauri's generated wrapper requests. ENV GRADLE_VERSION=8.14.3 \ GRADLE_HOME=/opt/gradle/gradle-8.14.3 RUN mkdir -p /opt/gradle/dist && \ wget -q "https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip" \ -O "/opt/gradle/dist/gradle-${GRADLE_VERSION}-bin.zip" && \ unzip -q "/opt/gradle/dist/gradle-${GRADLE_VERSION}-bin.zip" -d /opt/gradle && \ "$GRADLE_HOME/bin/gradle" --version ENV PATH="$GRADLE_HOME/bin:$PATH" # --------------------------------------------------------------------------- # Desktop packaging tools — kept in a trailing layer ON PURPOSE so that adding # or changing a packaging tool doesn't invalidate the expensive apt/rust/Android # layers above (a tool tweak becomes a ~1-2 min rebuild, not ~15). Covers Linux # (deb/rpm) and Windows cross (MSVC via cargo-xwin + NSIS). RUN apt-get update && apt-get install -y --no-install-recommends \ # Linux desktop packaging: rpmbuild for the .rpm bundle (deb needs nothing extra) rpm \ file \ # Windows cross-compile (official Tauri path: MSVC target via cargo-xwin). # clang provides clang-cl, the MSVC-compatible C compiler cc-rs uses to build # C deps (bundled sqlite, ring, ...); lld = linker; llvm = llvm-lib/ar etc; # nsis = installer generator. clang \ lld \ llvm \ nsis \ && rm -rf /var/lib/apt/lists/* \ # Ubuntu's clang package ships clang but NOT the clang-cl alias that cc-rs # invokes for MSVC targets. clang-cl is the same binary in MSVC-compat mode, # so provide it as a symlink. && ln -sf /usr/bin/clang /usr/local/bin/clang-cl # Windows rust target + cargo-xwin (downloads the MSVC CRT/SDK at build time). RUN . $HOME/.cargo/env && \ rustup target add x86_64-pc-windows-msvc && \ cargo install --locked cargo-xwin WORKDIR /app ENTRYPOINT ["/bin/bash"]