Androidアプリのビルドによう使うツールをインストールしたDocker Imageの作り方を説明する(Android SDK, Flutter SDK, GCloud, Bundler, Firebase tools)。
Dockerを使ったことはあるが、実用的なDocker Imageを作ったことはない人向けの説明。

Docker Imageを作る手順

1. Dockerfileを記述する

# BaseはCircle CIのものにする。android sdk, gcloudが既に入っているので楽。
FROM circleci/android:api-29-node

# Install firebase tools
RUN sudo curl -sL https://firebase.tools | bash

# Install tools for easylauncher
RUN sudo apt-get update && sudo apt-get install -y fontconfig ttf-dejavu

# Install Flutter SDK
# ほぼ以下のファイルのコピペ。flutter_verisonの初期化とprecacheの部分は独自。
# https://github.com/cirruslabs/docker-images-flutter/blob/master/sdk/Dockerfile
ARG flutter_version=1.20.1

ENV FLUTTER_HOME=${HOME}/sdks/flutter \
    FLUTTER_VERSION=$flutter_version
ENV FLUTTER_ROOT=$FLUTTER_HOME

ENV PATH ${PATH}:${FLUTTER_HOME}/bin:${FLUTTER_HOME}/bin/cache/dart-sdk/bin

RUN git clone --branch ${FLUTTER_VERSION} https://github.com/flutter/flutter.git ${FLUTTER_HOME}

RUN flutter precache

RUN yes | flutter doctor --android-licenses && flutter doctor

2. Docker Imageをビルドする

上記のDockerfileと同じディレクトリで以下のコマンドを実行する。

docker build -t kamikazezirou/android:1.0 .

「kamikazezirou/android」の部分はImage名。
「:1.0」は、ImageのTag。
適宜変更すること。

3. Docker ImageをDocker Hubにpushする

docker push kamikazezirou/android:1.0

※docker loginでDocker Hubにログインしておくこと。アカウントも必要。

4. CIから使う(Cirlce CIでの例)

jobs:
  build:
    working_directory: ~/code
    docker:
      - image: kamikazezirou/android:1.0
...

背景

仕事で開発しているアプリで、Android Native onlyのアプリにFlutterモジュールを組み込むことになった。
仕事のAndroidアプリ開発ではCirlce CIを使っているが、その設定をしていて、ビルドツール全部入りのDocker Imageが必要になった。

CIのワークフローはは、デバッグapkのビルド -> Firebase Test Lab実行 -> リリースビルドというような流れにしている。最初は、ビルドのDocker Imageには「cirrusci/flutter:1.17.5」を使い、Firebase Test Labの実行のDocker Imageには「circleci/android:api-28-node」を使う、といった形にしようとした(前者はFlutter SDK有り かつ GCloudなし。後者はFlutter SDKなし かつ GCloudあり)。

この方式だと2つ問題があった。

  1. 依存ライブラリのキャッシュの復元時にエラーが発生した(2つのDocker Imageのhomeディレクトリが違うことが原因)
  2. この2つのDocker Imageに含まれないビルドツールがあり、それらを毎回インストールする必要があった(→ビルド時間が遅くなる、ビルドスクリプトが雑然とする)

この2つの問題を解決するために、ビルドツール全部入りのDocker Imageを作ろうと思い立った。
1つのDocker Imageであればhomeディレクトリは常に同じであり、ビルドツールのインストール処理も不要。

参考:作ったDocker Image

https://hub.docker.com/repository/docker/kamikazezirou/android