From 48273887383756f1becef50d51ec15741bd4bdac Mon Sep 17 00:00:00 2001 From: Mathias Beaulieu-Duncan Date: Mon, 2 Feb 2026 17:55:20 -0500 Subject: [PATCH] Migrate to Wolfi base image and optimize SDK size - Switch all Dockerfiles from debian:bookworm-slim to svrnty/base-distro:flutter-sdk-latest (Wolfi) - Use non-root user (UID 65532) instead of custom flutter user - Strip wrong-platform engine artifacts per variant (web, android, linux) - Remove dev/, examples/ and compact .git with git gc --prune=all - Android: multi-stage build for JDK 17 + Android SDK 36 from Debian - Linux: multi-stage build for clang/cmake/ninja/GTK3 with glibc conflict resolution - Update Android SDK from 35 to 36 (required by Flutter 3.38.9) Image sizes: web 1.32 GB, linux 2.43 GB, android 4.22 GB (down from 4.9 GB, 3.69 GB, 4.15 GB respectively) Co-Authored-By: Claude Opus 4.5 --- Dockerfile | 38 +++++++++------------- Dockerfile.android | 66 ++++++++++++++++++++++++------------- Dockerfile.linux | 81 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 120 insertions(+), 65 deletions(-) diff --git a/Dockerfile b/Dockerfile index b81511f..91c24de 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,31 +1,29 @@ -FROM debian:bookworm-slim +FROM svrnty/base-distro:flutter-sdk-latest ARG FLUTTER_VERSION=3.38.9 -LABEL org.opencontainers.image.title="flutter-sdk" +LABEL org.opencontainers.image.title="flutter-sdk-web" LABEL org.opencontainers.image.description="Minimal Flutter SDK for Web/WASM CI builds" LABEL org.opencontainers.image.version="${FLUTTER_VERSION}" -# Install minimal dependencies for Flutter web builds -RUN apt-get update && apt-get install -y --no-install-recommends \ - curl \ - git \ - unzip \ - xz-utils \ - ca-certificates \ - && rm -rf /var/lib/apt/lists/* +USER 0 -ENV FLUTTER_HOME=/opt/flutter -ENV PATH="${FLUTTER_HOME}/bin:${FLUTTER_HOME}/bin/cache/dart-sdk/bin:${PATH}" - -# Download Flutter SDK from official archive +# Download Flutter SDK and strip unnecessary files in a single layer RUN curl -fsSL "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz" \ -o /tmp/flutter.tar.xz && \ tar xf /tmp/flutter.tar.xz -C /opt && \ - rm /tmp/flutter.tar.xz + rm /tmp/flutter.tar.xz && \ + rm -rf /opt/flutter/dev \ + /opt/flutter/examples \ + /opt/flutter/bin/cache/artifacts/engine/android-* \ + /opt/flutter/bin/cache/artifacts/engine/linux-* && \ + chown -R 65532:65532 /opt/flutter -# Mark git directory as safe (tarball is owned by different uid) -RUN git config --global --add safe.directory "${FLUTTER_HOME}" +# Mark git directory as safe and compact git history +RUN git config --global --add safe.directory /opt/flutter && \ + cd /opt/flutter && git gc --prune=all + +USER 65532 # Configure for web-only (disable everything else) RUN flutter config --enable-web \ @@ -48,10 +46,4 @@ RUN flutter precache --web \ # Verify installation RUN flutter doctor -v -# Create non-root user for CI builds -RUN groupadd -r flutter && useradd -r -g flutter -m -d /home/flutter flutter && \ - chown -R flutter:flutter "${FLUTTER_HOME}" /home/flutter - WORKDIR /app -RUN chown flutter:flutter /app -USER flutter diff --git a/Dockerfile.android b/Dockerfile.android index a296b9b..e793079 100644 --- a/Dockerfile.android +++ b/Dockerfile.android @@ -1,27 +1,30 @@ -FROM debian:bookworm-slim +FROM svrnty/base-distro:flutter-sdk-latest AS base ARG FLUTTER_VERSION=3.38.9 ARG ANDROID_SDK_TOOLS_VERSION=11076708 -ARG ANDROID_COMPILE_SDK=35 -ARG ANDROID_BUILD_TOOLS=35.0.1 +ARG ANDROID_COMPILE_SDK=36 +ARG ANDROID_BUILD_TOOLS=36.0.0 -LABEL org.opencontainers.image.title="flutter-sdk" +LABEL org.opencontainers.image.title="flutter-sdk-android" LABEL org.opencontainers.image.description="Flutter SDK for Android CI builds" LABEL org.opencontainers.image.version="${FLUTTER_VERSION}" -# Install dependencies for Flutter + Android SDK +# --- Install JDK and Android SDK in debian (requires apt + shared libs) --- +FROM debian:bookworm-slim AS android-stage + +ARG ANDROID_SDK_TOOLS_VERSION=11076708 +ARG ANDROID_COMPILE_SDK=36 +ARG ANDROID_BUILD_TOOLS=36.0.0 + RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ - git \ unzip \ - xz-utils \ - ca-certificates \ openjdk-17-jdk-headless \ && rm -rf /var/lib/apt/lists/* -# Android SDK +ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 ENV ANDROID_HOME=/opt/android-sdk -ENV PATH="${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${PATH}" +ENV PATH="${JAVA_HOME}/bin:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${PATH}" RUN mkdir -p "${ANDROID_HOME}/cmdline-tools" && \ curl -fsSL "https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS_VERSION}_latest.zip" \ @@ -30,25 +33,48 @@ RUN mkdir -p "${ANDROID_HOME}/cmdline-tools" && \ mv /tmp/cmdline-tools/cmdline-tools "${ANDROID_HOME}/cmdline-tools/latest" && \ rm -rf /tmp/cmdline-tools.zip /tmp/cmdline-tools -# Accept licenses and install SDK components RUN yes | sdkmanager --licenses > /dev/null 2>&1 && \ sdkmanager --install \ "platform-tools" \ "platforms;android-${ANDROID_COMPILE_SDK}" \ "build-tools;${ANDROID_BUILD_TOOLS}" -# Flutter SDK -ENV FLUTTER_HOME=/opt/flutter -ENV PATH="${FLUTTER_HOME}/bin:${FLUTTER_HOME}/bin/cache/dart-sdk/bin:${PATH}" +# --- Build final image --- +FROM base +USER 0 + +# Copy JDK and its required shared libraries from debian +COPY --from=android-stage /usr/lib/jvm/java-17-openjdk-amd64 /usr/lib/jvm/java-17-openjdk-amd64 +COPY --from=android-stage /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu +COPY --from=android-stage /lib/x86_64-linux-gnu /lib/x86_64-linux-gnu +ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 +ENV PATH="${JAVA_HOME}/bin:${PATH}" + +# Copy Android SDK (already set up with licenses and components) +COPY --from=android-stage /opt/android-sdk /opt/android-sdk +ENV ANDROID_HOME=/opt/android-sdk +ENV PATH="${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${PATH}" + +# Download Flutter SDK and strip unnecessary files in a single layer RUN curl -fsSL "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz" \ -o /tmp/flutter.tar.xz && \ tar xf /tmp/flutter.tar.xz -C /opt && \ - rm /tmp/flutter.tar.xz + rm /tmp/flutter.tar.xz && \ + rm -rf /opt/flutter/dev \ + /opt/flutter/examples \ + /opt/flutter/bin/cache/artifacts/engine/linux-* \ + /opt/flutter/bin/cache/flutter_web_sdk -RUN git config --global --add safe.directory "${FLUTTER_HOME}" +RUN git config --global --add safe.directory /opt/flutter && \ + cd /opt/flutter && git gc --prune=all -# Configure for Android-only +# Fix ownership before switching to flutter user +RUN chown -R 65532:65532 /opt/flutter "${ANDROID_HOME}" + +USER 65532 + +# Configure Flutter for Android-only RUN flutter config --enable-android \ --no-enable-web \ --no-enable-ios \ @@ -69,10 +95,4 @@ RUN flutter precache --android \ RUN flutter doctor -v -# Create non-root user for CI builds -RUN groupadd -r flutter && useradd -r -g flutter -m -d /home/flutter flutter && \ - chown -R flutter:flutter "${FLUTTER_HOME}" "${ANDROID_HOME}" /home/flutter - WORKDIR /app -RUN chown flutter:flutter /app -USER flutter diff --git a/Dockerfile.linux b/Dockerfile.linux index 9a62793..9fa499e 100644 --- a/Dockerfile.linux +++ b/Dockerfile.linux @@ -1,18 +1,15 @@ -FROM debian:bookworm-slim +FROM svrnty/base-distro:flutter-sdk-latest AS base ARG FLUTTER_VERSION=3.38.9 -LABEL org.opencontainers.image.title="flutter-sdk" +LABEL org.opencontainers.image.title="flutter-sdk-linux" LABEL org.opencontainers.image.description="Flutter SDK for Linux desktop CI builds" LABEL org.opencontainers.image.version="${FLUTTER_VERSION}" -# Install dependencies for Flutter + Linux desktop builds +# --- Install Linux desktop build deps in debian --- +FROM debian:bookworm-slim AS deps-stage + RUN apt-get update && apt-get install -y --no-install-recommends \ - curl \ - git \ - unzip \ - xz-utils \ - ca-certificates \ clang \ cmake \ ninja-build \ @@ -22,17 +19,69 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libstdc++-12-dev \ && rm -rf /var/lib/apt/lists/* -ENV FLUTTER_HOME=/opt/flutter -ENV PATH="${FLUTTER_HOME}/bin:${FLUTTER_HOME}/bin/cache/dart-sdk/bin:${PATH}" +# --- Build final image --- +FROM base +USER 0 + +# Download Flutter SDK and strip unnecessary files in a single layer RUN curl -fsSL "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz" \ -o /tmp/flutter.tar.xz && \ tar xf /tmp/flutter.tar.xz -C /opt && \ - rm /tmp/flutter.tar.xz + rm /tmp/flutter.tar.xz && \ + rm -rf /opt/flutter/dev \ + /opt/flutter/examples \ + /opt/flutter/bin/cache/artifacts/engine/android-* \ + /opt/flutter/bin/cache/flutter_web_sdk -RUN git config --global --add safe.directory "${FLUTTER_HOME}" +RUN git config --global --add safe.directory /opt/flutter && \ + cd /opt/flutter && git gc --prune=all -# Configure for Linux desktop only +# Remove symlinks that conflict with COPY from debian stage +RUN rm -f /usr/lib/terminfo + +# Copy only specific toolchain binaries (not all of /usr/bin which would overwrite Wolfi's core utils) +COPY --from=deps-stage /usr/bin/cmake /usr/bin/cmake +COPY --from=deps-stage /usr/bin/ninja /usr/bin/ninja +COPY --from=deps-stage /usr/bin/pkg-config /usr/bin/pkg-config +COPY --from=deps-stage /usr/bin/clang-14 /usr/bin/clang-14 +RUN ln -sf clang-14 /usr/bin/clang && ln -sf clang-14 /usr/bin/clang++ + +# Copy libraries from debian stage (specific subdirectories to avoid overwriting Wolfi's core libs) +COPY --from=deps-stage /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu +COPY --from=deps-stage /usr/lib/llvm-14 /usr/lib/llvm-14 +COPY --from=deps-stage /usr/lib/cmake /usr/lib/cmake +COPY --from=deps-stage /usr/lib/gcc /usr/lib/gcc +COPY --from=deps-stage /usr/include /usr/include +COPY --from=deps-stage /usr/share/cmake-3.25 /usr/share/cmake-3.25 +COPY --from=deps-stage /usr/share/pkgconfig /usr/share/pkgconfig +COPY --from=deps-stage /lib/x86_64-linux-gnu /lib/x86_64-linux-gnu + +# Remove Debian's glibc/ld files that conflict with Wolfi's newer glibc, +# then register the Debian library paths and rebuild the linker cache +RUN rm -f /usr/lib/x86_64-linux-gnu/libc.so* /usr/lib/x86_64-linux-gnu/libm.so* \ + /usr/lib/x86_64-linux-gnu/libpthread* /usr/lib/x86_64-linux-gnu/libdl.so* \ + /usr/lib/x86_64-linux-gnu/librt.so* /usr/lib/x86_64-linux-gnu/libresolv* \ + /usr/lib/x86_64-linux-gnu/libmvec* /usr/lib/x86_64-linux-gnu/libnss_* \ + /usr/lib/x86_64-linux-gnu/ld-linux* /usr/lib/x86_64-linux-gnu/crt*.o \ + /usr/lib/x86_64-linux-gnu/libpcre2-8.so* \ + /lib/x86_64-linux-gnu/libc.so* /lib/x86_64-linux-gnu/libc-* \ + /lib/x86_64-linux-gnu/libm.so* /lib/x86_64-linux-gnu/libm-* \ + /lib/x86_64-linux-gnu/libpthread* /lib/x86_64-linux-gnu/libdl.so* \ + /lib/x86_64-linux-gnu/librt.so* /lib/x86_64-linux-gnu/libresolv* \ + /lib/x86_64-linux-gnu/libmvec* /lib/x86_64-linux-gnu/libnss_* \ + /lib/x86_64-linux-gnu/ld-linux* \ + /lib/x86_64-linux-gnu/libpcre2-8.so* && \ + echo "/usr/lib/x86_64-linux-gnu" > /etc/ld.so.conf.d/debian-x86_64.conf && \ + echo "/lib/x86_64-linux-gnu" >> /etc/ld.so.conf.d/debian-x86_64.conf && \ + ldconfig + +# Fix ownership before switching to flutter user +RUN chown -R 65532:65532 /opt/flutter + +USER 65532 + +# Configure Flutter for Linux desktop only RUN flutter config --enable-linux-desktop \ --no-enable-web \ --no-enable-android \ @@ -52,10 +101,4 @@ RUN flutter precache --linux \ RUN flutter doctor -v -# Create non-root user for CI builds -RUN groupadd -r flutter && useradd -r -g flutter -m -d /home/flutter flutter && \ - chown -R flutter:flutter "${FLUTTER_HOME}" /home/flutter - WORKDIR /app -RUN chown flutter:flutter /app -USER flutter