| # Copyright 2022 The Flutter Authors. All rights reserved. | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| # This is a highly opinionated docker container aimed at getting a developer | |
| # up and running with antigravity in a sandbox, instantly. | |
| # Build: | |
| # x86: docker build -t flutter_docker . | |
| # Apple Silicon: podman build --platform linux/amd64 -t flutter_docker . | |
| # Different version of fluttr: podman build --platform linux/amd64 --build-arg FLUTTER_VERSION=3.45.0 -t flutter_docker:3.45.0 . | |
| # | |
| # Run: | |
| # Apple Silicon: podman run --platform linux/amd64 -it -v "${PWD}:/app" -v "dart_tool_cache:/app/.dart_tool" -v "dart_build_cache:/app/build" -v "$USER/.gemini:/home/coder/.gemini" flutter_docker:latest | |
| # x86: docker run -it -v ".:/app" -v 'dart_tool_cache:/app/.dart_tool' -v "dart_build_cache:/app/build" -v "$USER/.gemini:/home/coder/.gemini" flutter_docker:latest | |
| # | |
| # Doing something work worktrees - work in progress? | |
| # 1. Make sure you have relative paths setup. | |
| # git config --global worktree.useRelativePaths true | |
| # git worktree repair | |
| # 2. Run one of the commands above, but from the worktree folder. | |
| # | |
| # Versions: | |
| # * latest: 3.44.2 | |
| # * previous: 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 | |
| # 1. Define the ARG with a fallback default version | |
| ARG FLUTTER_VERSION="3.44.2" | |
| 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_${FLUTTER_VERSION}-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/coder/.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 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 software-properties-common lrzsz; \ | |
| # Install trzsz via PPA | |
| add-apt-repository ppa:trzsz/ppa -y; \ | |
| add-apt-repository ppa:git-core/ppa -y; \ | |
| apt-get update; \ | |
| apt-get install -y trzsz git; \ | |
| # 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 "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers | |
| # 3. User setup and directory creation | |
| # Using -m automatically creates the home directory securely. | |
| RUN groupadd -r coder && \ | |
| useradd -r -m -g coder coder && \ | |
| mkdir -p /app /opt/flutter /home/linuxbrew/.linuxbrew && \ | |
| chown -R coder:coder /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=coder:coder /opt/flutter /opt/flutter | |
| # Switch context to the non-root user for the remaining installations | |
| USER coder | |
| # 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/coder/.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/coder/.config/byobu && \ | |
| touch /home/coder/.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/coder/.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 coder:coder /app/.dart_tool"'; \ | |
| echo 'run-shell "sudo mkdir -p /app/build && sudo chown -R coder:coder /app/build"'; \ | |
| echo 'run-shell "sudo mkdir -p /home/coder/.gemini && sudo chown -R coder:coder /home/coder/.gemini"'; \ | |
| } > /home/coder/.config/byobu/profile.tmux && \ | |
| touch /home/coder/.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 ."; \ | |
| echo ": 1000000000:0;dart analyze ."; \ | |
| } >> /home/coder/.zsh_history && \ | |
| touch /home/coder/.zshrc && \ | |
| { \ | |
| echo 'alias agyolo="agy --dangerously-skip-permissions"'; \ | |
| } >> /home/coder/.zshrc | |
| RUN mkdir -p /home/coder/.vim/pack/dart-lang/start && \ | |
| git clone https://github.com/dart-lang/dart-vim-plugin /home/coder/.vim/pack/dart-lang/start/dart-vim-plugin | |
| RUN git config --global --add safe.directory /app && \ | |
| git config --global core.editor vim && \ | |
| git config --global pull.rebase true | |
| WORKDIR /app | |
| ENTRYPOINT [ "/usr/bin/byobu" ] |