Compare commits

...

37 Commits
3.38.9 ... main

Author SHA1 Message Date
github-actions[bot]
518b7b33c0 Update base image digests (Wolfi security update) 2026-02-04 13:00:08 +00:00
Mathias Beaulieu-Duncan
33ad166ce8 Make versioned tags immutable
Some checks failed
Check for Flutter SDK, Android SDK, and Base Image Updates / check-update (push) Failing after 8s
- Full release (3.38.9): creates web-3.38.9 + web-latest
- Prerelease (3.38.9-rebuild-20260203): creates web-3.38.9-rebuild-20260203 + web-dev
- Versioned tags never get overwritten after initial publish

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 04:25:21 -05:00
Mathias Beaulieu-Duncan
3aa55f7590 Add Wolfi base image update detection
- Check base image digests daily against stored values
- Trigger prerelease rebuild when Wolfi updates detected
- Store digests in .base-digests file

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 04:19:56 -05:00
Mathias Beaulieu-Duncan
8605e967b1 Add static Docker Hub README
Simplified version without dynamic badges or images table.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 04:11:12 -05:00
Mathias Beaulieu-Duncan
4bdf6bb162 Skip README sync for test releases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 04:09:32 -05:00
Mathias Beaulieu-Duncan
a5fb4b3584 Move README sync into publish workflow
- Add sync-readme job that runs after builds complete
- Uses release tag directly (no API call needed)
- Only runs for full releases, not prereleases
- Remove separate sync-readme-badges.yaml workflow

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 04:08:28 -05:00
Mathias Beaulieu-Duncan
f54b8f37ae Get Flutter version from release tag instead of Dockerfile
The build uses --build-arg to override the Dockerfile default,
so README sync should read from the actual release tag.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 04:07:01 -05:00
Mathias Beaulieu-Duncan
dffc5a151e Note Gitea/GitHub Actions cross-compatibility
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 04:02:38 -05:00
Mathias Beaulieu-Duncan
c4c88e2e05 Simplify CI/CD section to Gitea Actions only
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 04:01:59 -05:00
Mathias Beaulieu-Duncan
6e5707d36a Change Linux desktop example to Debian arm64
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 04:01:05 -05:00
Mathias Beaulieu-Duncan
b21965fd8d Add sws.toml config for proper WASM headers
COOP/COEP headers required for SharedArrayBuffer (WASM multi-threading).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:58:47 -05:00
Mathias Beaulieu-Duncan
26797d954d Update web example with WASM build and static-web-server
- Use --wasm flag for WebAssembly compilation
- Add cache-busting for JS/WASM assets
- Replace nginx with static-web-server on scratch (~18MB)
- Run as non-root user

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:56:27 -05:00
Mathias Beaulieu-Duncan
b5ccf2effa Remove dev tag from documentation
The -dev tag was only used for pipeline testing.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:53:53 -05:00
Mathias Beaulieu-Duncan
a92326374d Replace CLI examples with multi-stage Dockerfile examples
- Web: Build app and serve with nginx
- Android: Extract APK from multi-stage build
- Linux: Build desktop app with minimal runtime
- Consolidated CI/CD section

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:53:29 -05:00
Mathias Beaulieu-Duncan
eeaf0d00a5 Use darker orange for amd64 badges to complement arm64 green
Changed from standard orange to #E65100 (deep orange) for better
visual balance with the #2e7d32 dark green arm64 badges.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:50:53 -05:00
Mathias Beaulieu-Duncan
d6ea6233d7 Make arch badges clickable to Docker Hub tags page
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:48:44 -05:00
Mathias Beaulieu-Duncan
00fd040d67 Use darker green for arm64 badge, add separator
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:48:06 -05:00
Mathias Beaulieu-Duncan
63c6385410 Add colored arch badges: amd64 orange, arm64 green
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:46:59 -05:00
Mathias Beaulieu-Duncan
e8a9efce53 Use actual version tags in variant table, remove latest badge
- Show web-3.38.9, android-3.38.9, linux-3.38.9 instead of generic names
- Remove Docker Version latest badge
- Update sync workflow to also update Flutter versions in badges

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:46:24 -05:00
Mathias Beaulieu-Duncan
950e0c8877 Move Git Repository badge to first position
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:45:07 -05:00
Mathias Beaulieu-Duncan
4ebb852202 Trigger badge sync only after build workflow completes
Use workflow_run instead of push trigger to ensure badges
update after images are actually built.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:44:45 -05:00
Mathias Beaulieu-Duncan
5264393e39 Fix size badges to use existing -dev tags
The -latest tags don't exist yet, use -dev tags for size display.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:43:37 -05:00
Mathias Beaulieu-Duncan
ef7281a710 Add workflow to auto-sync README badges with Dockerfile versions
Automatically updates Android SDK version badge when Dockerfile changes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:42:48 -05:00
Mathias Beaulieu-Duncan
5d5634c4a1 Add Android SDK version badge
Links to Android build-tools release notes page.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:41:43 -05:00
Mathias Beaulieu-Duncan
b574607caf Add dynamic badges to images table
- Clickable Docker badges linking to specific tag pages
- Dynamic image sizes from Docker Hub
- Architecture column showing amd64/arm64 support

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:40:05 -05:00
Mathias Beaulieu-Duncan
091a50fe1a Fix badge URLs and use HTML for new tab links
- Remove broken Docker Scout and SLSA badges
- Remove LICENSE badge (no LICENSE file)
- Fix image size badge to use version instead
- Add Wolfi base badge
- Use HTML anchor tags with target="_blank"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:38:53 -05:00
Mathias Beaulieu-Duncan
7336904388 Add badges for Docker Hub, Git, pulls, size, and compliance
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:35:42 -05:00
Mathias Beaulieu-Duncan
88046dda7f Update README with friendlier tone
Focus on Wolfi benefits rather than competitor comparisons.
Highlight lightweight nature and automatic updates.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:33:34 -05:00
Mathias Beaulieu-Duncan
09c23f66ff Add README with usage examples and size comparison
Document the Flutter SDK Docker images with:
- Image variants and sizes
- Comparison showing 75% smaller than alternatives
- CI/CD examples for GitHub, GitLab, and Gitea
- Security features (zero CVEs, SBOM, provenance)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:32:22 -05:00
Mathias Beaulieu-Duncan
68b6e6ec54 Remove rav1e to eliminate paste crate CVE in Linux image
All checks were successful
Build and Push Flutter SDK Image / build-and-push (Flutter SDK for Linux desktop CI builds, Dockerfile.linux, linux) (release) Successful in 21m10s
Build and Push Flutter SDK Image / build-and-push (Flutter SDK for Android CI builds, Dockerfile.android, android) (release) Successful in 28m35s
Build and Push Flutter SDK Image / build-and-push (Minimal Flutter SDK for Web/WASM CI builds, Dockerfile, web) (release) Successful in 16m45s
Remove rav1e binary, library, and SBOM metadata to eliminate
RUSTSEC-2024-0436 in the paste crate. rav1e (AV1 encoder) is not
needed for Flutter Linux desktop development.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 03:01:29 -05:00
Mathias Beaulieu-Duncan
553fee0a25 Upgrade commons-lang3 to fix CVE-2025-48924
Replace vulnerable commons-lang3 3.16.0 with fixed version 3.18.0
to resolve CVE-2025-48924 (CVSS 6.5 Medium).

Image now has 0 vulnerabilities across all severity levels.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 02:45:13 -05:00
Mathias Beaulieu-Duncan
b2e4c09c2b Use git clone for Flutter SDK to support arm64
All checks were successful
Build and Push Flutter SDK Image / build-and-push (Flutter SDK for Linux desktop CI builds, Dockerfile.linux, linux) (release) Successful in 26m24s
Build and Push Flutter SDK Image / build-and-push (Flutter SDK for Android CI builds, Dockerfile.android, android) (release) Successful in 31m44s
Build and Push Flutter SDK Image / build-and-push (Minimal Flutter SDK for Web/WASM CI builds, Dockerfile, web) (release) Successful in 16m45s
Switch from downloading pre-built Flutter SDK tarballs to cloning from
git. Flutter only provides x64 Linux tarballs, but cloning from git
allows Flutter to bootstrap itself with the correct Dart SDK for any
host architecture (amd64 or arm64).

Also reduces image size from ~4GB to ~1.7GB for Android variant.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 02:06:52 -05:00
Mathias Beaulieu-Duncan
84b6f55c7a Remove lint-psi to eliminate protobuf-java CVEs
Some checks failed
Build and Push Flutter SDK Image / build-and-push (Flutter SDK for Linux desktop CI builds, Dockerfile.linux, linux) (release) Failing after 23m47s
Build and Push Flutter SDK Image / build-and-push (Flutter SDK for Android CI builds, Dockerfile.android, android) (release) Failing after 26m25s
Build and Push Flutter SDK Image / build-and-push (Minimal Flutter SDK for Web/WASM CI builds, Dockerfile, web) (release) Has been cancelled
Consolidate Android SDK download and setup into single layer to ensure
lint-psi directory (containing vulnerable protobuf-java 2.6.1) is never
committed to any image layer. Reduces CVEs from 4 HIGH to 0 and saves 86MB.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 01:32:52 -05:00
Mathias Beaulieu-Duncan
a8331e9516 Update Android SDK to latest versions and add version check workflow
- Update cmdline-tools from 11076708 to 14742923 (v20.0)
- Update build-tools from 36.0.0 to 36.1.0
- Add Android SDK version checking to update-check workflow
- Creates issues when Android SDK updates are available

This reduces CVEs from 26 to 4 (all from protobuf-java 2.6.1 bundled by Google).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 00:47:15 -05:00
Mathias Beaulieu-Duncan
935a638ee3 Add multi-arch support (amd64 + arm64) for all Flutter SDK variants
- Add QEMU setup for cross-platform builds
- Build web, android, and linux images for both amd64 and arm64

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 00:32:45 -05:00
Mathias Beaulieu-Duncan
ec0e419275 Use native Wolfi base images for Android and Linux variants
- Dockerfile.android: Use flutter-sdk-android-latest base with OpenJDK 17
- Dockerfile.linux: Use flutter-sdk-linux-latest base with clang/GTK3

Removes all Debian library copying, eliminating Debian-sourced CVEs.
Significantly simplifies both Dockerfiles.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 23:49:12 -05:00
4827388738 Migrate to Wolfi base image and optimize SDK size
All checks were successful
Build and Push Flutter SDK Image / build-and-push (Flutter SDK for Linux desktop CI builds, Dockerfile.linux, linux) (release) Successful in 1h8m47s
Build and Push Flutter SDK Image / build-and-push (Flutter SDK for Android CI builds, Dockerfile.android, android) (release) Successful in 1h11m0s
Build and Push Flutter SDK Image / build-and-push (Minimal Flutter SDK for Web/WASM CI builds, Dockerfile, web) (release) Successful in 6m49s
- 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 <noreply@anthropic.com>
2026-02-02 17:55:20 -05:00
8 changed files with 538 additions and 108 deletions

3
.base-digests Normal file
View File

@ -0,0 +1,3 @@
web=sha256:cce6d72541facea17321cb7f76fc8947c54335a3675cabe64214efad366240f4
android=sha256:489f3cbd316bd66d3475430b69e1b32f87606a63f8837c3588b04da83b7509ff
linux=sha256:2c77cba8eb20114f45d7b9d97d5d6773fa542c72cb6252d6f1c00de9fb4c7e95

View File

@ -5,7 +5,7 @@ on:
types: [published, prereleased] types: [published, prereleased]
permissions: permissions:
contents: read contents: write
env: env:
IMAGE_NAME: flutter-sdk IMAGE_NAME: flutter-sdk
@ -33,18 +33,23 @@ jobs:
id: version id: version
run: | run: |
if [[ "${{ github.event.release.prerelease }}" == "true" ]]; then if [[ "${{ github.event.release.prerelease }}" == "true" ]]; then
# Pre-release: fetch latest stable version, tag as dev # Pre-release: use release tag as version, don't overwrite existing tags
FLUTTER_VERSION=$(curl -fsSL https://storage.googleapis.com/flutter_infra_release/releases/releases_linux.json \ # Extract base Flutter version for build-arg (e.g., 3.38.9 from 3.38.9-rebuild-20260203)
| jq -r '.current_release.stable as $hash | .releases[] | select(.hash == $hash and .channel == "stable") | .version') BASE_VERSION=$(echo "${{ github.event.release.tag_name }}" | grep -oP '^[0-9]+\.[0-9]+\.[0-9]+')
echo "flutter_version=${FLUTTER_VERSION}" >> $GITHUB_OUTPUT echo "flutter_version=${BASE_VERSION}" >> $GITHUB_OUTPUT
echo "tag=${{ matrix.variant }}-dev" >> $GITHUB_OUTPUT echo "tag=${{ matrix.variant }}-${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
echo "Using latest Flutter stable ${FLUTTER_VERSION} for pre-release test" echo "secondary_tag=${{ matrix.variant }}-dev" >> $GITHUB_OUTPUT
echo "Pre-release: building Flutter ${BASE_VERSION}, tagging as ${{ github.event.release.tag_name }}"
else else
# Full release: use the release tag as the Flutter version # Full release: use the release tag as the Flutter version
echo "flutter_version=${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT echo "flutter_version=${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
echo "tag=${{ matrix.variant }}-latest" >> $GITHUB_OUTPUT echo "tag=${{ matrix.variant }}-${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
echo "secondary_tag=${{ matrix.variant }}-latest" >> $GITHUB_OUTPUT
fi fi
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
@ -64,7 +69,7 @@ jobs:
load: true load: true
build-args: | build-args: |
FLUTTER_VERSION=${{ steps.version.outputs.flutter_version }} FLUTTER_VERSION=${{ steps.version.outputs.flutter_version }}
tags: ${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-${{ steps.version.outputs.flutter_version }} tags: ${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.tag }}
- name: Install Docker Scout - name: Install Docker Scout
run: | run: |
@ -73,24 +78,59 @@ jobs:
- name: Docker Scout CVE Scan - name: Docker Scout CVE Scan
run: | run: |
docker scout cves ${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-${{ steps.version.outputs.flutter_version }} --only-severity critical,high docker scout cves ${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.tag }} --only-severity critical,high
- name: Build and push with attestations - name: Build and push with attestations
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
context: . context: .
file: ${{ matrix.dockerfile }} file: ${{ matrix.dockerfile }}
platforms: linux/amd64 platforms: linux/amd64,linux/arm64
push: true push: true
sbom: true sbom: true
provenance: mode=max provenance: mode=max
build-args: | build-args: |
FLUTTER_VERSION=${{ steps.version.outputs.flutter_version }} FLUTTER_VERSION=${{ steps.version.outputs.flutter_version }}
tags: | tags: |
${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ matrix.variant }}-${{ steps.version.outputs.flutter_version }}
${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.tag }} ${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.tag }}
${{ secrets.REGISTRY_URL }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.secondary_tag }}
labels: | labels: |
org.opencontainers.image.title=${{ env.IMAGE_NAME }} org.opencontainers.image.title=${{ env.IMAGE_NAME }}
org.opencontainers.image.description=${{ matrix.description }} org.opencontainers.image.description=${{ matrix.description }}
org.opencontainers.image.version=${{ matrix.variant }}-${{ steps.version.outputs.flutter_version }} org.opencontainers.image.version=${{ steps.version.outputs.tag }}
org.opencontainers.image.revision=${{ github.sha }} org.opencontainers.image.revision=${{ github.sha }}
sync-readme:
needs: build-and-push
if: github.event.release.prerelease == false && !contains(github.event.release.tag_name, 'test')
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Update README badges
run: |
FLUTTER="${{ github.event.release.tag_name }}"
ANDROID_SDK=$(grep -oP 'ANDROID_BUILD_TOOLS=\K[0-9.]+' Dockerfile.android || echo "")
if [ -n "$ANDROID_SDK" ]; then
sed -i "s|Android%20SDK-[0-9.]*-green|Android%20SDK-${ANDROID_SDK}-green|g" README.md
fi
if [ -n "$FLUTTER" ]; then
sed -i "s|web--[0-9.]*-blue|web--${FLUTTER}-blue|g" README.md
sed -i "s|android--[0-9.]*-blue|android--${FLUTTER}-blue|g" README.md
sed -i "s|linux--[0-9.]*-blue|linux--${FLUTTER}-blue|g" README.md
sed -i "s|/web-[0-9.]*?|/web-${FLUTTER}?|g" README.md
sed -i "s|/android-[0-9.]*?|/android-${FLUTTER}?|g" README.md
sed -i "s|/linux-[0-9.]*?|/linux-${FLUTTER}?|g" README.md
fi
- name: Commit and push
run: |
git diff --quiet README.md && exit 0
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add README.md
git commit -m "Update README badges to Flutter ${{ github.event.release.tag_name }}"
git push

View File

@ -1,4 +1,4 @@
name: Check for Flutter SDK Updates name: Check for Flutter SDK, Android SDK, and Base Image Updates
on: on:
schedule: schedule:
@ -9,6 +9,9 @@ jobs:
check-update: check-update:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Get latest Flutter stable version - name: Get latest Flutter stable version
id: flutter id: flutter
run: | run: |
@ -17,7 +20,47 @@ jobs:
echo "version=${LATEST}" >> $GITHUB_OUTPUT echo "version=${LATEST}" >> $GITHUB_OUTPUT
echo "Latest Flutter stable: ${LATEST}" echo "Latest Flutter stable: ${LATEST}"
- name: Check if release already exists - name: Get latest Android SDK versions
id: android
run: |
REPO_XML=$(curl -fsSL "https://dl.google.com/android/repository/repository2-1.xml")
# Latest stable build-tools (exclude rc/alpha/beta)
BUILD_TOOLS=$(echo "$REPO_XML" | grep -o 'path="build-tools;[0-9]*\.[0-9]*\.[0-9]*"' | \
sed 's/path="build-tools;//;s/"//' | sort -V | tail -1)
# Latest stable platform
PLATFORM=$(echo "$REPO_XML" | grep -o 'path="platforms;android-[0-9]*"' | \
sed 's/path="platforms;android-//;s/"//' | sort -n | tail -1)
# Latest cmdline-tools download ID
CMDLINE_DOWNLOAD=$(echo "$REPO_XML" | grep -o 'commandlinetools-linux-[0-9]*_latest' | \
sed 's/commandlinetools-linux-//;s/_latest//' | sort -n | tail -1)
echo "build_tools=${BUILD_TOOLS}" >> $GITHUB_OUTPUT
echo "platform=${PLATFORM}" >> $GITHUB_OUTPUT
echo "cmdline_tools=${CMDLINE_DOWNLOAD}" >> $GITHUB_OUTPUT
echo "Latest Android build-tools: ${BUILD_TOOLS}"
echo "Latest Android platform: ${PLATFORM}"
echo "Latest cmdline-tools download: ${CMDLINE_DOWNLOAD}"
- name: Check current Android SDK versions in Dockerfile
id: current
run: |
CURRENT_CMDLINE=$(grep -o 'ANDROID_SDK_TOOLS_VERSION=[0-9]*' Dockerfile.android | cut -d= -f2)
CURRENT_BUILD_TOOLS=$(grep -o 'ANDROID_BUILD_TOOLS=[0-9.]*' Dockerfile.android | cut -d= -f2)
CURRENT_PLATFORM=$(grep -o 'ANDROID_COMPILE_SDK=[0-9]*' Dockerfile.android | cut -d= -f2)
echo "cmdline_tools=${CURRENT_CMDLINE}" >> $GITHUB_OUTPUT
echo "build_tools=${CURRENT_BUILD_TOOLS}" >> $GITHUB_OUTPUT
echo "platform=${CURRENT_PLATFORM}" >> $GITHUB_OUTPUT
echo "Current cmdline-tools: ${CURRENT_CMDLINE}"
echo "Current build-tools: ${CURRENT_BUILD_TOOLS}"
echo "Current platform: ${CURRENT_PLATFORM}"
- name: Check if Flutter release already exists
id: existing id: existing
run: | run: |
VERSION="${{ steps.flutter.outputs.version }}" VERSION="${{ steps.flutter.outputs.version }}"
@ -31,7 +74,99 @@ jobs:
echo "Release ${VERSION} not found, will create" echo "Release ${VERSION} not found, will create"
fi fi
- name: Create release for new version - name: Determine if Android SDK update is needed
id: android_update
run: |
NEEDS_UPDATE=false
if [ "${{ steps.android.outputs.cmdline_tools }}" != "${{ steps.current.outputs.cmdline_tools }}" ]; then
echo "cmdline-tools update available: ${{ steps.current.outputs.cmdline_tools }} -> ${{ steps.android.outputs.cmdline_tools }}"
NEEDS_UPDATE=true
fi
if [ "${{ steps.android.outputs.build_tools }}" != "${{ steps.current.outputs.build_tools }}" ]; then
echo "build-tools update available: ${{ steps.current.outputs.build_tools }} -> ${{ steps.android.outputs.build_tools }}"
NEEDS_UPDATE=true
fi
if [ "${{ steps.android.outputs.platform }}" != "${{ steps.current.outputs.platform }}" ]; then
echo "platform update available: ${{ steps.current.outputs.platform }} -> ${{ steps.android.outputs.platform }}"
NEEDS_UPDATE=true
fi
echo "needs_update=${NEEDS_UPDATE}" >> $GITHUB_OUTPUT
- name: Check Wolfi base image updates
id: base_images
run: |
# Get current digests from Docker Hub
WEB_DIGEST=$(curl -s "https://hub.docker.com/v2/repositories/svrnty/base-distro/tags/flutter-sdk-latest" | jq -r '.digest // empty')
ANDROID_DIGEST=$(curl -s "https://hub.docker.com/v2/repositories/svrnty/base-distro/tags/flutter-sdk-android-latest" | jq -r '.digest // empty')
LINUX_DIGEST=$(curl -s "https://hub.docker.com/v2/repositories/svrnty/base-distro/tags/flutter-sdk-linux-latest" | jq -r '.digest // empty')
echo "Current base image digests:"
echo " web: ${WEB_DIGEST}"
echo " android: ${ANDROID_DIGEST}"
echo " linux: ${LINUX_DIGEST}"
# Load stored digests
STORED_WEB=$(grep '^web=' .base-digests 2>/dev/null | cut -d= -f2 || echo "")
STORED_ANDROID=$(grep '^android=' .base-digests 2>/dev/null | cut -d= -f2 || echo "")
STORED_LINUX=$(grep '^linux=' .base-digests 2>/dev/null | cut -d= -f2 || echo "")
# Compare
NEEDS_REBUILD=false
if [ -n "$WEB_DIGEST" ] && [ "$WEB_DIGEST" != "$STORED_WEB" ]; then
echo "Web base image updated"
NEEDS_REBUILD=true
fi
if [ -n "$ANDROID_DIGEST" ] && [ "$ANDROID_DIGEST" != "$STORED_ANDROID" ]; then
echo "Android base image updated"
NEEDS_REBUILD=true
fi
if [ -n "$LINUX_DIGEST" ] && [ "$LINUX_DIGEST" != "$STORED_LINUX" ]; then
echo "Linux base image updated"
NEEDS_REBUILD=true
fi
echo "needs_rebuild=${NEEDS_REBUILD}" >> $GITHUB_OUTPUT
echo "web_digest=${WEB_DIGEST}" >> $GITHUB_OUTPUT
echo "android_digest=${ANDROID_DIGEST}" >> $GITHUB_OUTPUT
echo "linux_digest=${LINUX_DIGEST}" >> $GITHUB_OUTPUT
- name: Trigger rebuild for base image updates
if: steps.base_images.outputs.needs_rebuild == 'true' && steps.existing.outputs.exists == 'true'
run: |
VERSION="${{ steps.flutter.outputs.version }}"
echo "Base image updated, triggering rebuild for Flutter ${VERSION}"
# Update stored digests
cat > .base-digests << EOF
web=${{ steps.base_images.outputs.web_digest }}
android=${{ steps.base_images.outputs.android_digest }}
linux=${{ steps.base_images.outputs.linux_digest }}
EOF
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add .base-digests
git commit -m "Update base image digests (Wolfi security update)"
git push
# Trigger rebuild by creating a prerelease
curl -fsSL -X POST \
-H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \
-H "Content-Type: application/json" \
"${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases" \
-d "{
\"tag_name\": \"${VERSION}-rebuild-$(date +%Y%m%d)\",
\"name\": \"Security rebuild ${VERSION}\",
\"body\": \"Automated rebuild for Wolfi base image security updates\",
\"draft\": false,
\"prerelease\": true
}"
- name: Create release for new Flutter version
if: steps.existing.outputs.exists == 'false' && steps.flutter.outputs.version != '' if: steps.existing.outputs.exists == 'false' && steps.flutter.outputs.version != ''
run: | run: |
VERSION="${{ steps.flutter.outputs.version }}" VERSION="${{ steps.flutter.outputs.version }}"
@ -47,3 +182,33 @@ jobs:
\"draft\": false, \"draft\": false,
\"prerelease\": false \"prerelease\": false
}" }"
- name: Create issue for Android SDK updates
if: steps.android_update.outputs.needs_update == 'true'
run: |
BODY="Android SDK updates are available:\n\n"
BODY+="| Component | Current | Latest |\n"
BODY+="|-----------|---------|--------|\n"
BODY+="| cmdline-tools | ${{ steps.current.outputs.cmdline_tools }} | ${{ steps.android.outputs.cmdline_tools }} |\n"
BODY+="| build-tools | ${{ steps.current.outputs.build_tools }} | ${{ steps.android.outputs.build_tools }} |\n"
BODY+="| platform | ${{ steps.current.outputs.platform }} | ${{ steps.android.outputs.platform }} |\n"
BODY+="\nUpdate \`Dockerfile.android\` to use the latest versions."
# Check if issue already exists
EXISTING=$(curl -s -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \
"${{ github.server_url }}/api/v1/repos/${{ github.repository }}/issues?state=open&labels=android-sdk-update" | jq length)
if [ "$EXISTING" = "0" ]; then
curl -fsSL -X POST \
-H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \
-H "Content-Type: application/json" \
"${{ github.server_url }}/api/v1/repos/${{ github.repository }}/issues" \
-d "{
\"title\": \"Android SDK updates available\",
\"body\": \"$(echo -e "$BODY")\",
\"labels\": [\"android-sdk-update\"]
}"
echo "Created issue for Android SDK updates"
else
echo "Issue for Android SDK updates already exists"
fi

131
DOCKERHUB.md Normal file
View File

@ -0,0 +1,131 @@
# Flutter SDK Docker Images
<a href="https://git.openharbor.io/svrnty/docker-flutter-sdk" target="_blank"><img src="https://img.shields.io/badge/Git-Repository-orange?logo=gitea" alt="Git Repository"></a>
<a href="https://wolfi.dev" target="_blank"><img src="https://img.shields.io/badge/Base-Wolfi-purple?logo=linux" alt="Wolfi"></a>
Lightweight Flutter SDK images for CI/CD pipelines. Built on [Wolfi](https://wolfi.dev), a security-focused Linux distribution designed for containers.
## Variants
- `web` - Web/WASM builds
- `android` - Android APK/AAB builds
- `linux` - Linux desktop builds
All variants support `linux/amd64` and `linux/arm64`.
## Why Wolfi?
[Wolfi](https://wolfi.dev) is a lightweight Linux distribution built specifically for containers. It provides:
- **Minimal footprint** - Only essential packages, nothing extra
- **Daily security updates** - Patches applied quickly
- **Designed for containers** - No legacy cruft from traditional distros
## Features
- **Lightweight** - Optimized for fast CI/CD pulls
- **Secure** - Built on Wolfi with continuous vulnerability scanning
- **Multi-arch** - Supports both `linux/amd64` and `linux/arm64`
- **Non-root** - Runs as unprivileged user (UID 65532)
- **Supply chain security** - SBOM and SLSA provenance attestations included
## Dockerfile Examples
### Web App (WASM)
```dockerfile
FROM svrnty/flutter-sdk:web-latest AS build
WORKDIR /app
COPY . .
RUN flutter pub get && flutter build web --wasm --release
# Cache-busting: append version to JS/WASM references
RUN VERSION=$(date +%s) && cd build/web && \
sed -i "s|flutter_bootstrap\.js\"|flutter_bootstrap.js?v=${VERSION}\"|g" index.html && \
sed -i "s|main\.dart\.js\"|main.dart.js?v=${VERSION}\"|g" flutter_bootstrap.js && \
sed -i "s|main\.dart\.mjs\"|main.dart.mjs?v=${VERSION}\"|g" flutter_bootstrap.js && \
sed -i "s|main\.dart\.wasm\"|main.dart.wasm?v=${VERSION}\"|g" flutter_bootstrap.js
FROM ghcr.io/static-web-server/static-web-server:2 AS sws
FROM scratch
COPY --from=sws /static-web-server /static-web-server
COPY --from=build /app/build/web /public
COPY sws.toml /sws.toml
EXPOSE 8080
USER 65534
ENTRYPOINT ["/static-web-server", "--config-file", "/sws.toml"]
```
**sws.toml** - Required headers for WASM multi-threading:
```toml
[general]
host = "0.0.0.0"
port = 8080
root = "/public"
page-fallback = "/public/index.html"
compression = true
[[advanced.headers]]
source = "**"
[advanced.headers.headers]
Cross-Origin-Opener-Policy = "same-origin"
Cross-Origin-Embedder-Policy = "require-corp"
```
### Android APK
```dockerfile
FROM svrnty/flutter-sdk:android-latest AS build
WORKDIR /app
COPY . .
RUN flutter pub get && flutter build apk --release
FROM scratch
COPY --from=build /app/build/app/outputs/flutter-apk/app-release.apk /
```
### Linux Desktop
```dockerfile
FROM svrnty/flutter-sdk:linux-latest AS build
WORKDIR /app
COPY . .
RUN flutter pub get && flutter build linux --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y libgtk-3-0 && rm -rf /var/lib/apt/lists/*
COPY --from=build /app/build/linux/arm64/release/bundle /app
ENTRYPOINT ["/app/my_app"]
```
## CI/CD (Gitea/GitHub Actions)
```yaml
jobs:
build:
runs-on: ubuntu-latest
container:
image: svrnty/flutter-sdk:android-latest
steps:
- uses: actions/checkout@v4
- run: flutter pub get
- run: flutter build apk --release
```
## Tags
- `<variant>-latest` - Latest stable Flutter release
- `<variant>-<version>` - Specific Flutter version (e.g., `android-3.29.0`)
## Automatic Updates
Images are automatically rebuilt when:
- New Flutter stable versions are released
- Base image security updates are available
Every build is scanned and includes supply chain attestations (SBOM, SLSA provenance).
## License
MIT

View File

@ -1,31 +1,20 @@
FROM debian:bookworm-slim FROM svrnty/base-distro:flutter-sdk-latest
ARG FLUTTER_VERSION=3.38.9 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.description="Minimal Flutter SDK for Web/WASM CI builds"
LABEL org.opencontainers.image.version="${FLUTTER_VERSION}" LABEL org.opencontainers.image.version="${FLUTTER_VERSION}"
# Install minimal dependencies for Flutter web builds USER 0
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
git \
unzip \
xz-utils \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
ENV FLUTTER_HOME=/opt/flutter # Clone Flutter SDK from git (supports both amd64 and arm64)
ENV PATH="${FLUTTER_HOME}/bin:${FLUTTER_HOME}/bin/cache/dart-sdk/bin:${PATH}" RUN git clone --depth 1 --branch ${FLUTTER_VERSION} https://github.com/flutter/flutter.git /opt/flutter && \
git config --global --add safe.directory /opt/flutter && \
rm -rf /opt/flutter/dev /opt/flutter/examples && \
chown -R 65532:65532 /opt/flutter
# Download Flutter SDK from official archive USER 65532
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
# Mark git directory as safe (tarball is owned by different uid)
RUN git config --global --add safe.directory "${FLUTTER_HOME}"
# Configure for web-only (disable everything else) # Configure for web-only (disable everything else)
RUN flutter config --enable-web \ RUN flutter config --enable-web \
@ -48,10 +37,4 @@ RUN flutter precache --web \
# Verify installation # Verify installation
RUN flutter doctor -v 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 WORKDIR /app
RUN chown flutter:flutter /app
USER flutter

View File

@ -1,54 +1,51 @@
FROM debian:bookworm-slim FROM svrnty/base-distro:flutter-sdk-android-latest
ARG FLUTTER_VERSION=3.38.9 ARG FLUTTER_VERSION=3.38.9
ARG ANDROID_SDK_TOOLS_VERSION=11076708 ARG ANDROID_SDK_TOOLS_VERSION=14742923
ARG ANDROID_COMPILE_SDK=35 ARG ANDROID_COMPILE_SDK=36
ARG ANDROID_BUILD_TOOLS=35.0.1 ARG ANDROID_BUILD_TOOLS=36.1.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.description="Flutter SDK for Android CI builds"
LABEL org.opencontainers.image.version="${FLUTTER_VERSION}" LABEL org.opencontainers.image.version="${FLUTTER_VERSION}"
# Install dependencies for Flutter + Android SDK USER 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 # Set up Android SDK environment
ENV ANDROID_HOME=/opt/android-sdk ENV ANDROID_HOME=/opt/android-sdk
ENV PATH="${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${PATH}" ENV PATH="${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools:${PATH}"
# Download Android SDK command-line tools, install SDK components, and remove vulnerable lint-psi
RUN mkdir -p "${ANDROID_HOME}/cmdline-tools" && \ RUN mkdir -p "${ANDROID_HOME}/cmdline-tools" && \
curl -fsSL "https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS_VERSION}_latest.zip" \ curl -fsSL "https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS_VERSION}_latest.zip" \
-o /tmp/cmdline-tools.zip && \ -o /tmp/cmdline-tools.zip && \
unzip -q /tmp/cmdline-tools.zip -d /tmp/cmdline-tools && \ unzip -q /tmp/cmdline-tools.zip -d /tmp/cmdline-tools && \
mv /tmp/cmdline-tools/cmdline-tools "${ANDROID_HOME}/cmdline-tools/latest" && \ mv /tmp/cmdline-tools/cmdline-tools "${ANDROID_HOME}/cmdline-tools/latest" && \
rm -rf /tmp/cmdline-tools.zip /tmp/cmdline-tools rm -rf /tmp/cmdline-tools.zip /tmp/cmdline-tools && \
yes | sdkmanager --licenses > /dev/null 2>&1 && \
# Accept licenses and install SDK components
RUN yes | sdkmanager --licenses > /dev/null 2>&1 && \
sdkmanager --install \ sdkmanager --install \
"platform-tools" \ "platform-tools" \
"platforms;android-${ANDROID_COMPILE_SDK}" \ "platforms;android-${ANDROID_COMPILE_SDK}" \
"build-tools;${ANDROID_BUILD_TOOLS}" "build-tools;${ANDROID_BUILD_TOOLS}" && \
# Remove lint-psi to eliminate protobuf-java 2.6.1 CVEs (saves 86MB)
rm -rf "${ANDROID_HOME}/cmdline-tools/latest/lib/external/lint-psi" && \
# Upgrade commons-lang3 from 3.16.0 to 3.18.0 to fix CVE-2025-48924
rm -f "${ANDROID_HOME}/cmdline-tools/latest/lib/external/org/apache/commons/commons-lang3/3.16.0/commons-lang3-3.16.0.jar" && \
mkdir -p "${ANDROID_HOME}/cmdline-tools/latest/lib/external/org/apache/commons/commons-lang3/3.18.0" && \
curl -fsSL "https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.18.0/commons-lang3-3.18.0.jar" \
-o "${ANDROID_HOME}/cmdline-tools/latest/lib/external/org/apache/commons/commons-lang3/3.18.0/commons-lang3-3.18.0.jar"
# Flutter SDK # Clone Flutter SDK from git (supports both amd64 and arm64)
ENV FLUTTER_HOME=/opt/flutter RUN git clone --depth 1 --branch ${FLUTTER_VERSION} https://github.com/flutter/flutter.git /opt/flutter && \
ENV PATH="${FLUTTER_HOME}/bin:${FLUTTER_HOME}/bin/cache/dart-sdk/bin:${PATH}" git config --global --add safe.directory /opt/flutter && \
rm -rf /opt/flutter/dev /opt/flutter/examples
RUN curl -fsSL "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz" \ # Fix ownership before switching to flutter user
-o /tmp/flutter.tar.xz && \ RUN chown -R 65532:65532 /opt/flutter "${ANDROID_HOME}"
tar xf /tmp/flutter.tar.xz -C /opt && \
rm /tmp/flutter.tar.xz
RUN git config --global --add safe.directory "${FLUTTER_HOME}" USER 65532
# Configure for Android-only # Configure Flutter for Android-only
RUN flutter config --enable-android \ RUN flutter config --enable-android \
--no-enable-web \ --no-enable-web \
--no-enable-ios \ --no-enable-ios \
@ -69,10 +66,4 @@ RUN flutter precache --android \
RUN flutter doctor -v 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 WORKDIR /app
RUN chown flutter:flutter /app
USER flutter

View File

@ -1,38 +1,27 @@
FROM debian:bookworm-slim FROM svrnty/base-distro:flutter-sdk-linux-latest
ARG FLUTTER_VERSION=3.38.9 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.description="Flutter SDK for Linux desktop CI builds"
LABEL org.opencontainers.image.version="${FLUTTER_VERSION}" LABEL org.opencontainers.image.version="${FLUTTER_VERSION}"
# Install dependencies for Flutter + Linux desktop builds USER 0
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
git \
unzip \
xz-utils \
ca-certificates \
clang \
cmake \
ninja-build \
pkg-config \
libgtk-3-dev \
liblzma-dev \
libstdc++-12-dev \
&& rm -rf /var/lib/apt/lists/*
ENV FLUTTER_HOME=/opt/flutter # Remove rav1e to eliminate CVE in paste crate (not needed for Flutter)
ENV PATH="${FLUTTER_HOME}/bin:${FLUTTER_HOME}/bin/cache/dart-sdk/bin:${PATH}" RUN rm -f /usr/bin/rav1e /usr/lib/librav1e.so* /var/lib/db/sbom/rav1e-*.spdx.json
RUN curl -fsSL "https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${FLUTTER_VERSION}-stable.tar.xz" \ # Clone Flutter SDK from git (supports both amd64 and arm64)
-o /tmp/flutter.tar.xz && \ RUN git clone --depth 1 --branch ${FLUTTER_VERSION} https://github.com/flutter/flutter.git /opt/flutter && \
tar xf /tmp/flutter.tar.xz -C /opt && \ git config --global --add safe.directory /opt/flutter && \
rm /tmp/flutter.tar.xz rm -rf /opt/flutter/dev /opt/flutter/examples
RUN git config --global --add safe.directory "${FLUTTER_HOME}" # Fix ownership before switching to flutter user
RUN chown -R 65532:65532 /opt/flutter
# Configure for Linux desktop only USER 65532
# Configure Flutter for Linux desktop only
RUN flutter config --enable-linux-desktop \ RUN flutter config --enable-linux-desktop \
--no-enable-web \ --no-enable-web \
--no-enable-android \ --no-enable-android \
@ -52,10 +41,4 @@ RUN flutter precache --linux \
RUN flutter doctor -v 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 WORKDIR /app
RUN chown flutter:flutter /app
USER flutter

134
README.md Normal file
View File

@ -0,0 +1,134 @@
# Flutter SDK Docker Images
<a href="https://git.openharbor.io/svrnty/docker-flutter-sdk" target="_blank"><img src="https://img.shields.io/badge/Git-Repository-orange?logo=gitea" alt="Git Repository"></a>
<a href="https://hub.docker.com/r/svrnty/flutter-sdk" target="_blank"><img src="https://img.shields.io/badge/Docker%20Hub-svrnty%2Fflutter--sdk-blue?logo=docker" alt="Docker Hub"></a>
<a href="https://hub.docker.com/r/svrnty/flutter-sdk" target="_blank"><img src="https://img.shields.io/docker/pulls/svrnty/flutter-sdk?logo=docker" alt="Docker Pulls"></a>
<a href="https://developer.android.com/tools/releases/build-tools" target="_blank"><img src="https://img.shields.io/badge/Android%20SDK-36.1.0-green?logo=android" alt="Android SDK"></a>
<a href="https://wolfi.dev" target="_blank"><img src="https://img.shields.io/badge/Base-Wolfi-purple?logo=linux" alt="Wolfi"></a>
Lightweight Flutter SDK images for CI/CD pipelines. Built on [Wolfi](https://wolfi.dev), a security-focused Linux distribution designed for containers.
## Images
| Variant | Use Case | Size | Arch |
|---------|----------|------|------|
| <a href="https://hub.docker.com/r/svrnty/flutter-sdk/tags?name=web" target="_blank"><img src="https://img.shields.io/badge/flutter--sdk-web--3.38.9-blue?logo=docker" alt="web-3.38.9"></a> | Web/WASM builds | <img src="https://img.shields.io/docker/image-size/svrnty/flutter-sdk/web-3.38.9?label=&logo=docker" alt="size"> | <a href="https://hub.docker.com/r/svrnty/flutter-sdk/tags?name=web" target="_blank"><img src="https://img.shields.io/badge/amd64-E65100" alt="amd64"></a> &nbsp; <a href="https://hub.docker.com/r/svrnty/flutter-sdk/tags?name=web" target="_blank"><img src="https://img.shields.io/badge/arm64-2e7d32" alt="arm64"></a> |
| <a href="https://hub.docker.com/r/svrnty/flutter-sdk/tags?name=android" target="_blank"><img src="https://img.shields.io/badge/flutter--sdk-android--3.38.9-blue?logo=docker" alt="android-3.38.9"></a> | Android APK/AAB builds | <img src="https://img.shields.io/docker/image-size/svrnty/flutter-sdk/android-3.38.9?label=&logo=docker" alt="size"> | <a href="https://hub.docker.com/r/svrnty/flutter-sdk/tags?name=android" target="_blank"><img src="https://img.shields.io/badge/amd64-E65100" alt="amd64"></a> &nbsp; <a href="https://hub.docker.com/r/svrnty/flutter-sdk/tags?name=android" target="_blank"><img src="https://img.shields.io/badge/arm64-2e7d32" alt="arm64"></a> |
| <a href="https://hub.docker.com/r/svrnty/flutter-sdk/tags?name=linux" target="_blank"><img src="https://img.shields.io/badge/flutter--sdk-linux--3.38.9-blue?logo=docker" alt="linux-3.38.9"></a> | Linux desktop builds | <img src="https://img.shields.io/docker/image-size/svrnty/flutter-sdk/linux-3.38.9?label=&logo=docker" alt="size"> | <a href="https://hub.docker.com/r/svrnty/flutter-sdk/tags?name=linux" target="_blank"><img src="https://img.shields.io/badge/amd64-E65100" alt="amd64"></a> &nbsp; <a href="https://hub.docker.com/r/svrnty/flutter-sdk/tags?name=linux" target="_blank"><img src="https://img.shields.io/badge/arm64-2e7d32" alt="arm64"></a> |
## Why Wolfi?
[Wolfi](https://wolfi.dev) is a lightweight Linux distribution built specifically for containers. It provides:
- **Minimal footprint** - Only essential packages, nothing extra
- **Daily security updates** - Patches applied quickly
- **Designed for containers** - No legacy cruft from traditional distros
## Features
- **Lightweight** - Optimized for fast CI/CD pulls
- **Secure** - Built on Wolfi with continuous vulnerability scanning
- **Multi-arch** - Supports both `linux/amd64` and `linux/arm64`
- **Non-root** - Runs as unprivileged user (UID 65532)
- **Supply chain security** - SBOM and SLSA provenance attestations included
## Dockerfile Examples
### Web App (WASM)
```dockerfile
FROM svrnty/flutter-sdk:web-latest AS build
WORKDIR /app
COPY . .
RUN flutter pub get && flutter build web --wasm --release
# Cache-busting: append version to JS/WASM references
RUN VERSION=$(date +%s) && cd build/web && \
sed -i "s|flutter_bootstrap\.js\"|flutter_bootstrap.js?v=${VERSION}\"|g" index.html && \
sed -i "s|main\.dart\.js\"|main.dart.js?v=${VERSION}\"|g" flutter_bootstrap.js && \
sed -i "s|main\.dart\.mjs\"|main.dart.mjs?v=${VERSION}\"|g" flutter_bootstrap.js && \
sed -i "s|main\.dart\.wasm\"|main.dart.wasm?v=${VERSION}\"|g" flutter_bootstrap.js
FROM ghcr.io/static-web-server/static-web-server:2 AS sws
FROM scratch
COPY --from=sws /static-web-server /static-web-server
COPY --from=build /app/build/web /public
COPY sws.toml /sws.toml
EXPOSE 8080
USER 65534
ENTRYPOINT ["/static-web-server", "--config-file", "/sws.toml"]
```
**sws.toml** - Required headers for WASM multi-threading:
```toml
[general]
host = "0.0.0.0"
port = 8080
root = "/public"
page-fallback = "/public/index.html"
compression = true
[[advanced.headers]]
source = "**"
[advanced.headers.headers]
Cross-Origin-Opener-Policy = "same-origin"
Cross-Origin-Embedder-Policy = "require-corp"
```
### Android APK
```dockerfile
FROM svrnty/flutter-sdk:android-latest AS build
COPY . /app
WORKDIR /app
RUN flutter pub get && flutter build apk --release
FROM scratch
COPY --from=build /app/build/app/outputs/flutter-apk/app-release.apk /
```
### Linux Desktop
```dockerfile
FROM svrnty/flutter-sdk:linux-latest AS build
WORKDIR /app
COPY . .
RUN flutter pub get && flutter build linux --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y libgtk-3-0 && rm -rf /var/lib/apt/lists/*
COPY --from=build /app/build/linux/arm64/release/bundle /app
ENTRYPOINT ["/app/my_app"]
```
## CI/CD (Gitea/GitHub Actions)
```yaml
jobs:
build:
runs-on: ubuntu-latest
container:
image: svrnty/flutter-sdk:android-latest
steps:
- uses: actions/checkout@v4
- run: flutter pub get
- run: flutter build apk --release
```
## Tags
- `<variant>-latest` - Latest stable Flutter release
- `<variant>-<version>` - Specific Flutter version (e.g., `android-3.38.9`)
## Automatic Updates
Images are automatically rebuilt when:
- New Flutter stable versions are released
- Base image security updates are available
Every build is scanned and includes supply chain attestations (SBOM, SLSA provenance).
## License
MIT