Docker で Flutter 開発環境を作ってみる
なんで?
このスクラップ で Docker
にある程度慣れた。
Flutter
での開発環境を構築するときに、なるべく PC を汚さないように。
環境
- Macbook Air (M1, 2020)
- チップ: Apple M1
- Docker for Mac: 3.3.1
Container を作る
まずはコレから。
# Base image
FROM google/dart:2.12.4
# Maintainer
LABEL maintainer="nagakuta <xxx@example.com>"
# Workdir
WORKDIR /workspace
# Install Flutter using fvm
RUN dart pub global activate fvm
今回は Flutter
のバージョン管理に fvm
を利用することにした。
version: '3.8'
services:
<project_name>:
build:
context: .
dockerfile: flutter/Dockerfile
volumes:
# VSCode settings
- ../.vscode:/workspace/.vscode:cached
command: /bin/sh -c "while sleep 1000; do :; done"
env_file:
- flutter/.flutter.env
…が、この段階で docker compose build --no-cache
でビルドしてみると「qemu: uncaught target signal 6 (Aborted) - core dumped」と言われてしまう。
どうやら、fvm
を activate する時に実行される依存関係の解決時に何かが起きているらしい。
試しに google/dart
の Container 内に入って直接 fvm
を activate すると、一回目は必ず失敗するが、もう一度 activate を実行すると問題なく完了した。困る。
そして、なんと fvm install
で Flutter
のインスコもできなかった。困る。
もしかしたら、google/dart
の Base Image が gcr.io/google-appengine/debian10
だからかもしれない。確かそれって Distroless で、本当に必要最低限のものしか入ってない(と思う、多分)。
もしかしたら、
google/dart
の Base Image がgcr.io/google-appengine/debian10
だからかもしれない。確かそれって Distroless で、本当に必要最低限のものしか入ってない(と思う、多分)。
と思ったが、色々試した結果 apt-get
で落としてくる Dart
が aarch64(arm64)
に対応しておらず、それ故に MacOS が arm64
から gcr.io/google-appengine/devian10
を動かすために利用している仮想化技術である qemu
が「対応してないよ!」と怒っているんだろう、という結論に至った。
Dockerfile を見直す
google/dart
をベースにするとうまく動かせないので、Ubuntu
を Base Image にしてイチから構築してみる。
google/dart
の Dockerfile を参考に
まず試すのは、google/dart
の Dockerfile を参考にしながら Base Image を ubuntu に変更。
必要なコマンドラインツールも先んじてインスコしておく。
# Base image
-FROM google/dart:2.12.4
+FROM ubuntu:20.04
# Maintainer
LABEL maintainer="nagakuta <xxx@example.com>"
# Workdir
WORKDIR /workspace
+# Install Dart
+RUN apt-get update && \
+ apt-get install --no-install-recommends -y gnupg2 curl git ca-certificates apt-transport-https openssh-client && \
+ curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
+ curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list && \
+ curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_testing.list > /etc/apt/sources.list.d/dart_testing.list && \
+ curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_unstable.list > /etc/apt/sources.list.d/dart_unstable.list && \
+ apt-get update && \
+ apt-get install dart && \
+# Clean up
+RUN apt-get clean -y && \
+ apt-get autoremove -y && \
+ rm -rf /var/lib/apt/lists/*
+# Set paths
+ENV DART_SDK /usr/lib/dart
+ENV PATH $DART_SDK/bin:/root/.pub-cache/bin:$PATH
…が、E: Unable to locate package dart
と怒られる。ので、ここ の Linux でのインスコ方法を見ながら書き換えてみる。…が、同様のエラーを吐く。詰まる。
apt-get
→ zip で落としてこよう
諦めて qemu
が原因で apt-get
から直接 Dart
をインストールできない(できていても fvm
周りが動かない)ので、諦めて zip ファイルを落として動かすことにした。
Dart
を導入
# Base image
FROM ubuntu:20.04
# Maintainer
LABEL maintainer="nagakuta <xxx@example.com>"
# Workdir
WORKDIR /workspace
# Install Dart
RUN apt-get update && \
- apt-get install -y ca-certificates curl git unzip --no-install-recommends && \
+ apt-get install --no-install-recommends -y bash ca-certificates curl file git libglu1-mesa unzip xz-utils zip && \
- curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
- curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list && \
- curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_testing.list > /etc/apt/sources.list.d/dart_testing.list && \
- curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_unstable.list > /etc/apt/sources.list.d/dart_unstable.list && \
- apt-get update && \
- apt-get install dart && \
+ curl https://storage.googleapis.com/dart-archive/channels/stable/release/$DART_VERSION/sdk/dartsdk-linux-arm64-release.zip -o /tmp/dart-sdk.zip && \
+ unzip /tmp/dart-sdk.zip -d /usr/lib && rm /tmp/dart-sdk.zip
# Clean up
RUN apt-get clean -y && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*
# Set paths
ENV DART_SDK /usr/lib/dart-sdk
ENV PATH $DART_SDK/bin:/root/.pub-cache/bin:$PATH
Dart
の導入まではこれで OK 。
fvm
のインストール
まずは手動で Container 内に fvm
をインスコしてみる。
$ dart pub global activate fvm
...
$ which fvm
/root/.pub-cache/bin/fvm
$ fvm --version
2.0.3
よしよし。
fvm
を利用しての Flutter
インスコ
そして fvm install
で Flutter
をインストールする。
$ fvm install 2.0.6
...
Building flutter tool...
/lib64/ld-linux-x86-64.so.2: No such file or directory
と怒られてしまった。ld-linux-x86-64
ということは、arm64
では動かないのだろうか。ググる。
…が、特に有力な情報は見つからず。x86_64(amd64)
で起動すると qemu
起因のエラーを吐き、aarch64(arm64)
で起動すると /lib64/ld-linux-x86-64.so.2: No such file or directory
と怒られてしまう。詰んだ。
ちなみに、上記エラーがどこで吐かれているかというと、flutter_sdk
内の Dart
で flutter tool なるものを build しているときらしい。flutter_sdk/bin/cache
内の dart_sdk
を削除するたびに Flutter
側が Dart
をそのフォルダ内に clone しているから、何となーくそこなんだろうな、と。まだ何が起きているかのコードをきちんと読んだわけではないので憶測もあるけど。
そして僕は泣きながら macOS にふつーに Flutter
をインスコしたのだった😩😩😩
続報
Apple Silicon(M1)ではなく Intel な CPU なら問題なく環境構築できたので、その過程を以下にまとめていく予定。
環境
- MacBook Air (13インチ, Early 2015)
- プロセッサ: 2.2 GHz デュアルコアIntel Core i7
- Docker for Mac: 3.3.3
Container を作る
前回試した Dockerfile を元に、x86_64(amd64)
で動作するようにしてみる。
# Base image
FROM ubuntu:20.04
# Maintainer
LABEL maintainer="nagakuta <xxx@example.com>"
# Workdir
WORKDIR /workspace
# Install Dart
ARG DART_VERSION=2.13.0
RUN mkdir -p /usr/share/man/man1 && \
apt-get update && apt-get install -y --no-install-recommends tzdata && \
apt-get update && \
apt-get install -y --no-install-recommends bash ca-certificates clang cmake curl file git libglu1-mesa libgtk-3-dev ninja-build pkg-config unzip xz-utils zip && \
curl https://storage.googleapis.com/dart-archive/channels/stable/release/$DART_VERSION/sdk/dartsdk-linux-x64-release.zip -o /tmp/dart-sdk.zip && \
unzip /tmp/dart-sdk.zip -d /usr/lib && rm /tmp/dart-sdk.zip
# Install Flutter
ARG PATH=/usr/lib/dart-sdk/bin:$PATH
ARG PATH=/root/.pub-cache/bin:$PATH
ARG FLUTTER_VERSION=2.2.0
RUN dart pub global activate fvm --verbose && \
fvm doctor --verbose && \
fvm install $FLUTTER_VERSION --verbose && \
fvm use --force $FLUTTER_VERSION --verbose && \
fvm flutter config --enable-web --enable-linux-desktop --enable-macos-desktop --enable-windows-desktop --enable-android --enable-ios --enable-fuchsia && \
# fvm flutter precache --verbose && \
fvm flutter doctor --verbose
# Clean up
RUN apt-get clean -y && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*
# Set paths
ENV FVM_ROOT=/root/.pub-cache
ENV PATH $FVM_ROOT/bin:$PATH
これで docker compose build --no-cache
してみる。成功した、よしよし。
Flutter
プロジェクトを作成する
Container 内で Container 内にて fvm
を利用して Flutter
をインストールできているので、Container に入って Flutter
プロジェクトを生成してみる。
$ fvm flutter create foo
問題なく生成できた、よしよし。
生成されたプロジェクトを元に、マウントするファイルを docker-compose.yml
で指定する。
version: '3.8'
services:
<project_name>:
build:
context: .
dockerfile: flutter/Dockerfile
volumes:
# Flutter files
- ../.dart_tool:/workspace/.dart_tool:cached
- ../.fvm:/workspace/.fvm:cached
- ../android:/workspace/android:cached
- ../ios:/workspace/ios:cached
- ../lib:/workspace/lib:cached
- ../linux:/workspace/linux:cached
- ../macos:/workspace/macos:cached
- ../test:/workspace/test:cached
- ../web:/workspace/web:cached
- ../windows:/workspace/windows:cached
- ../.metadata:/workspace/.metadata:cached
- ../.packages:/workspace/.packages:cached
- ../analysis_options.yaml:/workspace/analysis_options.yaml:cached
- ../<project_name>.iml:/workspace/<project_name>.iml:cached
- ../pubspec.lock:/workspace/pubspec.lock:cached
- ../pubspec.yaml:/workspace/pubspec.yaml:cached
- ../README.md:/workspace/README.md:cached
# VSCode settings
- ../.vscode:/workspace/.vscode:cached
command: /bin/sh -c "while sleep 1000; do :; done"
env_file:
- flutter/.flutter.env
これで必要なファイルのみが Container にマウントされるようになった、よしよし。
VSCode
で Dart
と Flutter
のための設定
最後に ここ を参考にしながら、 VSCode
で Dart
と Flutter
のための設定をする。
{
"dart.flutterSdkPath": ".fvm/flutter_sdk",
"debug.openDebug": "openOnDebugBreak",
"[dart]": {
"editor.rulers": [
80
],
"editor.selectionHighlight": false,
"editor.suggest.snippetsPreventQuickSuggestions": false,
"editor.suggestSelection": "first",
"editor.tabCompletion": "onlySnippets",
"editor.wordBasedSuggestions": false,
"editor.wordWrap": "bounded",
"editor.wordWrapColumn": 80
},
"files.exclude": {
".fvm/flutter_sdk": true
},
"files.watcherExclude": {
"**/.fvm": true
},
"search.exclude": {
"**/.fvm": true
}
}
これで最強の Flutter
開発環境を作り上げることができた。満足。
追記
最近は Dart
の公式 Docker image を利用して FVM 経由の Flutter インストールができるようになった。
# Base image
FROM dart:2.16-sdk
# Maintainer
LABEL maintainer="nagakuta <xxx@example.com>"
# Workdir
WORKDIR /workspace
# Install Flutter
ARG PATH=/root/.pub-cache/bin:$PATH
ARG FLUTTER_VERSION=2.10.5
RUN dart pub global activate melos --verbose && \
dart pub global activate fvm --verbose && \
fvm doctor --verbose && \
fvm install $FLUTTER_VERSION --verbose && \
fvm use --force $FLUTTER_VERSION --verbose && \
fvm flutter config --enable-web --enable-linux-desktop --enable-macos-desktop --enable-windows-desktop --enable-android --enable-ios --enable-fuchsia && \
# fvm flutter precache --verbose && \
fvm flutter doctor --verbose
# Set paths
ENV FVM_ROOT=/root/.pub-cache
ENV PATH $FVM_ROOT/bin:$PATH
これで Flutter のバージョンを管理しつつ Docker Container 内にインストールできるようになった。かなり簡潔になったと思う。
近々、記事の方も最新版に更新する予定。
記事更新 DONE