Sign inSign up

sinfallas/flutter-builder

By sinfallas

•Updated 3 days ago

Environment designed to be used in CI/CD pipelines to compile Android APK or bundle

Image
Languages & frameworks
Developer tools
0

647

sinfallas/flutter-builder repository overview

⁠flutter-builder

Docker Pulls Docker Image Size GitHub Repo

Ready-to-use CI/CD container image designed to compile modern Flutter Android APKs and App Bundles (AAB), and automate releases to the Google Play Store using Fastlane.

Pre-warmed with the complete Android SDK/NDK toolchain and container-safe Gradle JVM limits so builds start immediately without downloading gigabytes of dependencies or exhausting host RAM.


⁠🛠️ Stack & Pre-installed Versions

  • OS: Ubuntu 26.04 (linux/amd64)
  • Flutter: 3.47.9 (Stable Channel, pre-cached for Android)
  • Java: OpenJDK 21 LTS (JAVA_HOME pre-configured)
  • Gradle: 9.7.1 (System) & 9.3.1 (Pre-cached Flutter Gradle Wrapper + compiled flutter-gradle-plugin)
  • Android SDK Platforms: API 36 & API 35 (with accepted licenses for automatic provisioning of newer SDKs/NDKs)
  • Android Build Tools: 36.0.0 & 35.0.0
  • Android NDK & CMake: NDK 28.2.13676358 & CMake 3.22.1
  • Deployment & CLI Tools: Ruby + Fastlane, AWS CLI, Git, SSH

⁠✨ Key Features

  • Zero Cold-Start Downloads: Android SDK 36/35, NDK r28, CMake, and the default Flutter Gradle Wrapper are pre-installed and pre-warmed inside the image, with all SDK licenses pre-accepted for automatic on-demand provisioning if a project targets a newer API/NDK.
  • Container-Safe JVM Defaults: Pre-configured GRADLE_OPTS and $GRADLE_USER_HOME/gradle.properties (-Xmx2048m, MaxMetaspaceSize=512m, --no-daemon, workers.max=2) prevent OOM kills and swap thrashing caused by default -Xmx8G project templates.
  • Google Play Automation: Includes Fastlane (fastlane supply) out of the box for continuous delivery to internal, alpha, beta, or production tracks.

⁠🚀 Quick Start

⁠1. One-Liner APK Build (docker run)

Mount your Flutter project directory into /app and run:

docker run --rm \
  -v "$(pwd):/app" \
  -v flutter-gradle-cache:/root/.gradle \
  -v flutter-pub-cache:/root/.pub-cache \
  -v flutter-android-sdk-cache:/usr/local/android-sdk \
  sinfallas/flutter-builder:latest \
  bash -c "flutter pub get && flutter build apk --release -v"

The compiled APK will be generated at: ./build/app/outputs/flutter-apk/app-release.apk


⁠2. CI/CD Pipeline with Docker Compose

Create a docker-compose.yml next to your codigo_flutter/ directory:

services:
  build-apk:
    image: sinfallas/flutter-builder:latest
    profiles: ["dev", "pre"]
    container_name: ${hostname:-flutter_ci_runner}
    hostname: ${hostname:-flutter_ci_runner}
    pull_policy: ${pull_policy:-always}
    volumes:
      - ./codigo_flutter:/app
      - gradle-cache:/root/.gradle
      - pub-cache:/root/.pub-cache
      - android-sdk-cache:/usr/local/android-sdk
    working_dir: /app
    environment:
      - GRADLE_OPTS=${GRADLE_OPTS:--Dorg.gradle.jvmargs="-Xmx2048m -XX:MaxMetaspaceSize=512m -XX:ReservedCodeCacheSize=256m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8" -Dorg.gradle.daemon=false -Dorg.gradle.workers.max=2 -Dorg.gradle.caching=true}
    command: bash -c "flutter pub get && flutter build apk --release -v"

  build-publish-aab:
    image: sinfallas/flutter-builder:latest
    profiles: ["pro"]
    container_name: ${hostname:-flutter_ci_runner}
    hostname: ${hostname:-flutter_ci_runner}
    pull_policy: ${pull_policy:-always}
    volumes:
      - ./codigo_flutter:/app
      - gradle-cache:/root/.gradle
      - pub-cache:/root/.pub-cache
      - android-sdk-cache:/usr/local/android-sdk
      - ${PLAY_STORE_JSON_PATH:-/tmp/secrets/google-play.json}:/secrets/play_store_key.json:ro
    working_dir: /app
    environment:
      - GRADLE_OPTS=${GRADLE_OPTS:--Dorg.gradle.jvmargs="-Xmx2048m -XX:MaxMetaspaceSize=512m -XX:ReservedCodeCacheSize=256m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8" -Dorg.gradle.daemon=false -Dorg.gradle.workers.max=2 -Dorg.gradle.caching=true}
      - KEYSTORE_PASSWORD=${KEYSTORE_PASSWORD:-}
      - KEY_ALIAS=${KEY_ALIAS:-}
      - KEY_PASSWORD=${KEY_PASSWORD:-}
      - PACKAGE_NAME=${PACKAGE_NAME:-}
    command: >
      bash -c "flutter pub get && 
      flutter build appbundle --release -v && 
      cd android && 
      fastlane supply --track production --aab ../build/app/outputs/bundle/release/app-release.aab --json_key /secrets/play_store_key.json --package_name $$PACKAGE_NAME"

volumes:
  gradle-cache:
  pub-cache:
  android-sdk-cache:

Build Release APK (dev / pre profile):

docker compose --profile dev up --abort-on-container-exit
docker compose --profile dev down

Build AAB & Publish to Google Play (pro profile):

docker compose --profile pro up --abort-on-container-exit
docker compose --profile pro down

Tag summary

Content type

Image

Digest

sha256:6e51b56c6…

Size

4 GB

Last updated

3 days ago

docker pull sinfallas/flutter-builder