Created
June 5, 2026 00:26
-
-
Save jtmcdole/2ab7b98f0bcc1d89c2c9e3e6910ce2fa to your computer and use it in GitHub Desktop.
flutter + docker + antigravity
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # | |
| # Build: | |
| # x86: docker build -t flutter_docker . | |
| # Apple Silicon: docker build --platform linux/amd64 -t flutter_docker . | |
| # | |
| # Run: | |
| # Apple Silicon: podman run --platform linux/amd64 --rm -it -v "${PWD}:/app" -v "dart_tool_cache:/app/.dart_tool" -v "dart_build_cache:/app/build" -v "/Users/codefu/.gemini:/home/codefu/.gemini" flutter_docker:latest | |
| # x86: docker run --rm -it -v ".:/app" -v 'dart_tool_cache:/app/.dart_tool' -v "dart_build_cache:/app/build" -v "/Users/codefu/.gemini:/home/codefu/.gemini" flutter_docker:latest | |
| # | |
| # Doing something work worktrees? | |
| # podman run --platform linux/amd64 --rm -it -v "${PWD}:/app" -v "dart_tool_cache:/app/.dart_tool" -v "dart_build_cache:/app/build" -v "${PWD}/.git_docker:/app/.git" -v "${PWD}/../.bare:/app/.bare" -v "/Users/codefu/.gemini:/home/codefu/.gemini" flutter_docker:latest | |
| # | |
| # Versions: | |
| # * latest: permissions on ~/.gemini to fix tool calling | |
| # * previous: better handling of .dart_tool - see run commands above! flutter 3.44.1. allow my user to sudo | |
| # * previous: fix tmux key bindings. add less and rsync | |
| # * previous: `agyolo`!, -homebrew, +vim dart plugin, native yq/gh/jq, less RUN steps | |
| # * previous: zsh, omyzsh, homebrew. | |
| # * previous: multi-stage build for flutter tooling. byobu/tmux, git, jq. | |
| # ========================================== | |
| # STAGE 1: The Heavy Downloader - flutter and its tools are heavy | |
| # ========================================== | |
| FROM ubuntu:24.04 AS flutter-fetcher | |
| RUN apt-get update && \ | |
| apt-get install -y --no-install-recommends \ | |
| curl ca-certificates xz-utils git unzip && \ | |
| rm -rf /var/lib/apt/lists/* | |
| RUN useradd -m builder && \ | |
| mkdir -p /opt && \ | |
| chown builder:builder /opt | |
| USER builder | |
| WORKDIR /opt | |
| # This layer caches permanently until you change the URL. | |
| # It is completely immune to changes in your main image. | |
| RUN curl -fsSL https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.44.1-stable.tar.xz | tar -xJ | |
| # 2. Lock in configuration and force the massive SDK downloads | |
| ENV PATH="/opt/flutter/bin:${PATH}" | |
| RUN flutter config \ | |
| --enable-web \ | |
| --no-enable-linux-desktop \ | |
| --no-enable-macos-desktop \ | |
| --no-enable-windows-desktop \ | |
| --no-enable-android \ | |
| --no-enable-ios \ | |
| --no-enable-fuchsia && \ | |
| # Precache pulls down the engine binaries, Dart SDK, and web tools | |
| flutter precache --web && \ | |
| flutter --version | |
| # ========================================== | |
| # STAGE 2: The OS - which should mostly have an OCI layer already. | |
| # ========================================== | |
| FROM ubuntu:24.04 | |
| # 1. Environment Variables (Rarely change, define early) | |
| ENV TZ=America/Los_Angeles \ | |
| DEBIAN_FRONTEND=noninteractive \ | |
| FLUTTER_ROOT="/opt/flutter" \ | |
| PATH="/opt/flutter/bin:/home/codefu/.local/bin:${PATH}" \ | |
| LANG="en_US.UTF-8" \ | |
| LANGUAGE="en_US:en" \ | |
| LC_ALL="en_US.UTF-8" \ | |
| TERM="xterm-256color" \ | |
| COLORTERM="truecolor" \ | |
| SHELL="/usr/bin/zsh" | |
| # 2. OS Dependencies (Heavy layer, cache as much as possible) | |
| RUN set -eux; \ | |
| apt-get update; \ | |
| apt-get install -y --no-install-recommends \ | |
| ca-certificates curl dnsutils dos2unix git openssh-client unzip \ | |
| tmux byobu vim sudo xz-utils tzdata locales jq ripgrep \ | |
| fd-find fzf bat btop zsh build-essential procps file wget \ | |
| less rsync; \ | |
| # install github | |
| curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg; \ | |
| chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg; \ | |
| echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null; \ | |
| apt-get update && apt-get install -y gh; \ | |
| # binary yq | |
| wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64; \ | |
| chmod a+x /usr/local/bin/yq; \ | |
| locale-gen en_US.UTF-8; \ | |
| ln -s $(which fdfind) /usr/local/bin/fd; \ | |
| ln -s $(which batcat) /usr/local/bin/bat; \ | |
| ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone; \ | |
| rm -rf /var/lib/apt/lists/*; \ | |
| echo "codefu ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers | |
| # 3. User setup and directory creation | |
| # Using -m automatically creates the home directory securely. | |
| RUN groupadd -r codefu && \ | |
| useradd -r -m -g codefu codefu && \ | |
| mkdir -p /app /opt/flutter /home/linuxbrew/.linuxbrew && \ | |
| chown -R codefu:codefu /app /opt /home/linuxbrew | |
| # 4. Import the FULLY HYDRATED Flutter SDK from Stage 1 | |
| # This takes about 1 second and skips all network traffic. | |
| COPY --from=flutter-fetcher --chown=codefu:codefu /opt/flutter /opt/flutter | |
| # Switch context to the non-root user for the remaining installations | |
| USER codefu | |
| # or --disable-analytics if running as CICD | |
| RUN flutter --enable-analytics && dart --enable-analytics | |
| # 5. Install Oh My Zsh unattended so it doesn't halt the Docker build | |
| RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended | |
| # Set these after USER | |
| ENV PATH="/home/codefu/.pub-cache/bin:${PATH}" | |
| # 6. User-specific CLI tools | |
| RUN curl -fsSL https://antigravity.google/cli/install.sh | bash | |
| # 7. User Configuration (Highly volatile, keep at the very bottom) | |
| RUN mkdir -p /home/codefu/.config/byobu && \ | |
| touch /home/codefu/.config/byobu/.welcome-displayed && \ | |
| { \ | |
| echo "unbind-key -n C-a"; \ | |
| echo "set -g prefix C-a"; \ | |
| echo "set -g prefix2 F12"; \ | |
| echo "bind a send-prefix"; \ | |
| echo "# Ensure tmux handles control modifiers correctly for xterm"; \ | |
| echo "set-window-option -g xterm-keys on"; \ | |
| echo "# Clear any existing bindings for these keys";\ | |
| echo "unbind-key -n C-Left";\ | |
| echo "unbind-key -n C-Right";\ | |
| echo "# Map Ctrl + Left/Right to switch bottom tabs (windows)";\ | |
| echo "bind-key -n C-Left select-window -t :-";\ | |
| echo "bind-key -n C-Right select-window -t :+";\ | |
| echo "set -g mouse on"; \ | |
| } > /home/codefu/.config/byobu/keybindings.tmux && \ | |
| { \ | |
| echo "set -g default-terminal \"tmux-256color\""; \ | |
| echo "set -ag terminal-overrides \",xterm-256color:RGB\""; \ | |
| echo "set -g default-shell /usr/bin/zsh"; \ | |
| echo "# Automatically fix named volume permissions on startup"; \ | |
| echo 'run-shell "sudo mkdir -p /app/.dart_tool && sudo chown -R codefu:codefu /app/.dart_tool"'; \ | |
| echo 'run-shell "sudo mkdir -p /app/build && sudo chown -R codefu:codefu /app/build"'; \ | |
| echo 'run-shell "sudo mkdir -p /home/codefu/.gemini && sudo chown -R codefu:codefu /home/codefu/.gemini"'; \ | |
| } > /home/codefu/.config/byobu/profile.tmux && \ | |
| touch /home/codefu/.zsh_history && \ | |
| { \ | |
| echo ": 1000000000:0;dart pub global activate melos; melos pub-get"; \ | |
| echo ": 1000000000:0;flutter pub get"; \ | |
| echo ": 1000000000:0;flutter analyze ."; \ | |
| echo ": 1000000000:0;dart pub get"; \ | |
| echo ": 1000000000:0;dart format ."; \ | |
| } >> /home/codefu/.zsh_history && \ | |
| touch /home/codefu/.zshrc && \ | |
| { \ | |
| echo 'alias agyolo="agy --dangerously-skip-permissions"'; \ | |
| } >> /home/codefu/.zshrc | |
| RUN mkdir -p /home/codefu/.vim/pack/dart-lang/start && \ | |
| git clone https://github.com/dart-lang/dart-vim-plugin /home/codefu/.vim/pack/dart-lang/start/dart-vim-plugin | |
| RUN git config --global --add safe.directory /app | |
| WORKDIR /app | |
| ENTRYPOINT [ "/usr/bin/byobu" ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # | |
| # Build: | |
| # x86: docker build -t flutter_docker . | |
| # Apple Silicon: docker build --platform linux/amd64 -t flutter_docker . | |
| # | |
| # Run: | |
| # Apple Silicon: podman run --platform linux/amd64 --rm -it -v "${PWD}:/app" -v "dart_tool_cache:/app/.dart_tool" -v "dart_build_cache:/app/build" -v "/Users/codefu/.gemini:/home/codefu/.gemini" flutter_docker:latest | |
| # x86: docker run --rm -it -v ".:/app" -v 'dart_tool_cache:/app/.dart_tool' -v "dart_build_cache:/app/build" -v "/Users/codefu/.gemini:/home/codefu/.gemini" flutter_docker:latest | |
| # | |
| # Doing something work worktrees? | |
| # podman run --platform linux/amd64 --rm -it -v "${PWD}:/app" -v "dart_tool_cache:/app/.dart_tool" -v "dart_build_cache:/app/build" -v "${PWD}/.git_docker:/app/.git" -v "${PWD}/../.bare:/app/.bare" -v "/Users/codefu/.gemini:/home/codefu/.gemini" flutter_docker:latest | |
| # | |
| # Versions: | |
| # * latest: permissions on ~/.gemini to fix tool calling | |
| # * previous: better handling of .dart_tool - see run commands | |
| # * previous: bun + playwright install for gstack `install_gstack` | |
| # * previous: `agyolo`!, -homebrew, +vim dart plugin, native yq/gh/jq, less RUN steps | |
| # * previous: zsh, omyzsh, homebrew. | |
| # * previous: multi-stage build for flutter tooling. byobu/tmux, git, jq. | |
| # | |
| # ========================================== | |
| # STAGE 1: The Heavy Downloader - flutter and its tools are heavy | |
| # ========================================== | |
| FROM ubuntu:24.04 AS flutter-fetcher | |
| RUN apt-get update && \ | |
| apt-get install -y --no-install-recommends \ | |
| curl ca-certificates xz-utils git unzip && \ | |
| rm -rf /var/lib/apt/lists/* | |
| RUN useradd -m builder && \ | |
| mkdir -p /opt && \ | |
| chown builder:builder /opt | |
| USER builder | |
| WORKDIR /opt | |
| # This layer caches permanently until you change the URL. | |
| # It is completely immune to changes in your main image. | |
| RUN curl -fsSL https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.44.1-stable.tar.xz | tar -xJ | |
| # 2. Lock in configuration and force the massive SDK downloads | |
| ENV PATH="/opt/flutter/bin:${PATH}" | |
| RUN flutter config \ | |
| --enable-web \ | |
| --no-enable-linux-desktop \ | |
| --no-enable-macos-desktop \ | |
| --no-enable-windows-desktop \ | |
| --no-enable-android \ | |
| --no-enable-ios \ | |
| --no-enable-fuchsia && \ | |
| # Precache pulls down the engine binaries, Dart SDK, and web tools | |
| flutter precache --web && \ | |
| flutter --version | |
| # ========================================== | |
| # STAGE 2: The OS - Using Playwright Noble (Ubuntu 24.04) | |
| # ========================================== | |
| FROM mcr.microsoft.com/playwright:v1.49.0-noble | |
| # 1. Environment Variables (Rarely change, define early) | |
| ENV TZ=America/Los_Angeles \ | |
| DEBIAN_FRONTEND=noninteractive \ | |
| FLUTTER_ROOT="/opt/flutter" \ | |
| PLAYWRIGHT_BROWSERS_PATH="/ms-playwright" \ | |
| PATH="/opt/flutter/bin:/home/codefu/.local/bin:${PATH}" \ | |
| LANG="en_US.UTF-8" \ | |
| LANGUAGE="en_US:en" \ | |
| LC_ALL="en_US.UTF-8" \ | |
| TERM="xterm-256color" \ | |
| COLORTERM="truecolor" \ | |
| SHELL="/usr/bin/zsh" | |
| # 2. OS Dependencies (Heavy layer, cache as much as possible) | |
| RUN set -eux; \ | |
| apt-get update; \ | |
| apt-get install -y --no-install-recommends \ | |
| ca-certificates curl dnsutils dos2unix git openssh-client unzip \ | |
| tmux byobu vim sudo xz-utils tzdata locales jq ripgrep \ | |
| fd-find fzf bat btop zsh build-essential procps file wget \ | |
| less rsync; \ | |
| # install github | |
| curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg; \ | |
| chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg; \ | |
| echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null; \ | |
| apt-get update && apt-get install -y gh; \ | |
| # binary yq | |
| wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64; \ | |
| chmod a+x /usr/local/bin/yq; \ | |
| locale-gen en_US.UTF-8; \ | |
| ln -s $(which fdfind) /usr/local/bin/fd; \ | |
| ln -s $(which batcat) /usr/local/bin/bat; \ | |
| ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone; \ | |
| rm -rf /var/lib/apt/lists/*; \ | |
| echo "codefu ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers | |
| # 3. User setup and directory creation | |
| # Using -m automatically creates the home directory securely. | |
| RUN groupadd -r codefu && \ | |
| useradd -r -m -g codefu codefu && \ | |
| mkdir -p /app /opt/flutter /home/linuxbrew/.linuxbrew && \ | |
| chown -R codefu:codefu /app /opt /home/linuxbrew | |
| # 4. Import the FULLY HYDRATED Flutter SDK from Stage 1 | |
| # This takes about 1 second and skips all network traffic. | |
| COPY --from=flutter-fetcher --chown=codefu:codefu /opt/flutter /opt/flutter | |
| # 5. Import Bun directly from the official image (No curl | bash needed) | |
| COPY --from=oven/bun:latest /usr/local/bin/bun /usr/local/bin/bun | |
| RUN ln -s /usr/local/bin/bun /usr/local/bin/bunx | |
| # Switch context to the non-root user for the remaining installations | |
| USER codefu | |
| # or --disable-analytics if running as CICD | |
| RUN flutter --enable-analytics && dart --enable-analytics | |
| # 5. Install Oh My Zsh unattended so it doesn't halt the Docker build | |
| RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended | |
| # Set these after USER | |
| ENV PATH="/home/codefu/.pub-cache/bin:${PATH}" | |
| # 6. User-specific CLI tools | |
| RUN curl -fsSL https://antigravity.google/cli/install.sh | bash | |
| # 7. User Configuration (Highly volatile, keep at the very bottom) | |
| RUN mkdir -p /home/codefu/.config/byobu && \ | |
| touch /home/codefu/.config/byobu/.welcome-displayed && \ | |
| { \ | |
| echo "unbind-key -n C-a"; \ | |
| echo "set -g prefix C-a"; \ | |
| echo "set -g prefix2 F12"; \ | |
| echo "bind a send-prefix"; \ | |
| echo "# Ensure tmux handles control modifiers correctly for xterm"; \ | |
| echo "set-window-option -g xterm-keys on"; \ | |
| echo "# Clear any existing bindings for these keys";\ | |
| echo "unbind-key -n C-Left";\ | |
| echo "unbind-key -n C-Right";\ | |
| echo "# Map Ctrl + Left/Right to switch bottom tabs (windows)";\ | |
| echo "bind-key -n C-Left select-window -t :-";\ | |
| echo "bind-key -n C-Right select-window -t :+";\ | |
| echo "set -g mouse on"; \ | |
| } > /home/codefu/.config/byobu/keybindings.tmux && \ | |
| { \ | |
| echo "set -g default-terminal \"tmux-256color\""; \ | |
| echo "set -ag terminal-overrides \",xterm-256color:RGB\""; \ | |
| echo "set -g default-shell /usr/bin/zsh"; \ | |
| echo "# Automatically fix named volume permissions on startup"; \ | |
| echo 'run-shell "sudo mkdir -p /app/.dart_tool && sudo chown -R codefu:codefu /app/.dart_tool"'; \ | |
| echo 'run-shell "sudo mkdir -p /app/build && sudo chown -R codefu:codefu /app/build"'; \ | |
| echo 'run-shell "sudo mkdir -p /home/codefu/.gemini && sudo chown -R codefu:codefu /home/codefu/.gemini"'; \ | |
| } > /home/codefu/.config/byobu/profile.tmux && \ | |
| touch /home/codefu/.zsh_history && \ | |
| { \ | |
| echo ": 1000000000:0;dart pub global activate melos; melos pub-get"; \ | |
| echo ": 1000000000:0;flutter pub get"; \ | |
| echo ": 1000000000:0;flutter analyze ."; \ | |
| echo ": 1000000000:0;dart pub get"; \ | |
| echo ": 1000000000:0;dart format ."; \ | |
| } >> /home/codefu/.zsh_history && \ | |
| touch /home/codefu/.zshrc && \ | |
| { \ | |
| echo 'alias agyolo="agy --dangerously-skip-permissions"'; \ | |
| echo 'alias btop="btop --utf-force"'; \ | |
| echo ''; \ | |
| echo 'install_gstack() {'; \ | |
| echo ' git clone --single-branch --depth 1 https://github.com/garrytan/gstack.git /home/codefu/gstack || return 1'; \ | |
| echo ' pushd /home/codefu/gstack > /dev/null || return 1'; \ | |
| echo ' ./setup'; \ | |
| echo ' popd > /dev/null'; \ | |
| echo '}'; \ | |
| } >> /home/codefu/.zshrc | |
| RUN mkdir -p /home/codefu/.vim/pack/dart-lang/start && \ | |
| git clone https://github.com/dart-lang/dart-vim-plugin /home/codefu/.vim/pack/dart-lang/start/dart-vim-plugin | |
| RUN git config --global --add safe.directory /app | |
| WORKDIR /app | |
| ENTRYPOINT [ "/usr/bin/byobu" ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment