1. はじめに
Flutterの開発環境をDockerコンテナ (今回はUbuntu 20.04 LTS) に構築し、macOSやLinux OSのHost PCからあたかもHost PC上で開発しているのと同じような環境を構築する方法を紹介します。この仕組みを利用すれば、リモート (サーバー) に開発環境を構築し、それにローカルPCからアクセスしてFlutterアプリの開発が可能です。
Flutter in Docker全体像
(補足) 今回はトライしていませんが、Dockerコンテナ内にAndroid版 (Aundroid Studioを利用したエミュレータ上での動作) も原理上は動作可能なはずです。
Dockerコンテナ化するメリット (例)
- 開発環境を複製・削除し易く、同じ環境を第三者に配ることが可能
- 環境をDockerコンテナ化しておくとCI/CD時に便利
- OSに依存せず (Linux or macOS) 、Android/iOS以外の環境での動作確認が可能
ターゲット (Host PC) 環境
- macOS
- Linux OS (Flutter, Dockerが動作する64bit Linux環境であれば基本的にどのディストリービューションでもOK)
2. Dockerインストール
Docker自体のインストール方法については割愛しますが、基本的に公式サイトの手順通りに進めれば大丈夫です。
- macOS: Install Docker Desktop on Mac
- Linux (Ubuntu): Install Docker Engine on Ubuntu
3. Dockerコンテナイメージの作成
Dockerコンテナイメージを作成する手順について説明します。Dockerコンテナ内のOS (rootfs) はUbuntu 20.04にしました。今回はDockerfileは利用せず、全て手動による手順での説明です。
Ubuntu 20.04 イメージ (rootfs) の取得
$ docker pull ubuntu:20.04
Dockerコンテナの起動
以下のコマンドでDockerコンテナを起動してそのコンテナ中に入ります。基本的にセキュリティなし (--privileged
) で、Host PCのOSと同じ権限でアクセス出来るようにします。
なお、ここで指定したパラメータを後述のDocker-composeの設定ファイルでも利用するため、まずはこの設定のまま実行して下さい。
$ docker run -it --name flutter-docker ¥
--privileged -h flutter -u root -w /root ¥
--add-host=flutter:127.0.1.1 --net=host ubuntu:20.04
問題がなければプロンプトが#
に変わり、Dockerコンテナ内の操作に切り替わっています。例えば、uname
コマンドを打つとLinux OSになっていることが分かります。
# root@flutter:~# uname -a
Linux flutter 4.19.76-linuxkit #1 SMP Tue May 26 11:42:35 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
必要なツールのインストール
Dockerコンテナ内のUbuntu OSに必要なパッケージをインストールします。xserver-xorg
のインストール時にはロケールやキーボードの情報を求められますが、適当で良いです (無難ならUS) 。
# apt update
# apt install git unzip clang xserver-xorg pkg-config libgtk-3-dev curl cmake ninja-build
Chromeブラウザのインストール (必要があれば)
# apt install wget gnupg
# sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
# wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
# apt update
# apt-get install google-chrome-stable
参考: https://qiita.com/pyon_kiti_jp/items/e6032eb6061a4774aece
Flutter SDKのインストール
Flutter SDKをgit cloneして、/opt以下に配置します。
# git clone https://github.com/flutter/flutter.git
# mv flutter /opt/
コンテナイメージの保存
ここまででコンテナ内での作業は全て終了です。なので、コンテナから抜けます。
# exit
作成したコンテナをDockerイメージファイルとして保存します。ここで指定したパラメータを後述のDocker-composeの設定ファイルでも利用するため、まずはこの設定のまま実行して下さい。
$ docker commit flutter-docker flutter-docker/ubuntu:latest
4. Host PC側の設定 (macOSの場合のみ)
Dockerコンテナ内のGUIアプリケーションはX11プロトコルで動作するため、そのGUIアプリの画面をHost PC側のX11サーバーに転送する必要があります。macOSの場合、Host側のX11サーバーとしてXQuartzがありますので、それをインストールして利用します。
XQuartzのインストール
$ brew cask install xquartz
Host PCを再起動します。再起動後、DISPLAY
環境変数が以下のように設定されていることを確認します。
$ echo $DISPLAY
/private/tmp/com.apple.launchd.NagCeWDLYl/org.macosforge.xquartz:0
DockerコンテナのX11クライアントからのアクセスを許可します。
$ xhost +$(hostname)
$ xhost + local:root
コマンドラインもしくは、LaunchPadからXQuartz
を立ち上げておきます。
5. Host PC側の設定 (Linux OSの場合のみ)
Linux OSの場合は大抵がX11デフォルトだと思いますので、以下の対応だけを行います。
$ xhost + local:root
6. VSCode環境構築
VSCodeのインストールとVSCodeからDockerコンテナを利用するためのExtensions等をインストールします。
VSCodeのインストール
以下を参考にしてインストールしてください。
- Linux (Ubuntu): https://qiita.com/yoshiyasu1111/items/e21a77ed68b52cb5f7c8
- macOS: https://qiita.com/watamura/items/51c70fbb848e5f956fd6
VSCode Extensionsインストール
以下の3つのExtensionsをインストールします。
7. Docker Composeファイルの作成
VSCodeからDockerコンテナ内のFlutter SDKを利用するために、Docker Composeと先ほどインストールしたVSCode ExtensionsのRemote Development
の設定ファイルを作成します。作成したファイルは https://github.com/Kurun-pan/flutter-docker に置いているため、Host OS (Linux or macOS) に合わせて利用して下さい。
$ mkdir flutter_docker
$ cd flutter_docker
カレントディレクトリ (flutter_docker) 以下にdocker-compose.yml
ファイルと.devcontainer/devcontainer.json
ファイルの2つを作成します。
Host OSがmacOSの場合
DISPLAY
環境変数にhost.docker.internal:0
を設定するのがポイントのはずでしたが、上手く行かなかったため、{write your host name!!}
の部分はmacOSのhostnameを指定してください。。誰か正しい方法を知っていれば教えて下さい。
version: "3"
services:
flutter:
image: flutter-docker/ubuntu:latest
working_dir: /root/workspace
command: sleep infinity
environment:
- HOME=/root
- no_proxy=127.0.0.1,localhost
#- DISPLAY="host.docker.internal:0"
- DISPLAY={write your host name!!}:0
volumes:
- ~/.gitconfig:/home/root/.gitconfig
- ./:/root/workspace
- ~/.Xauthority:/root/.Xauthority
network_mode: "host"
extra_hosts:
- flutter:127.0.1.1
{
"name": "Flutter docker",
"dockerComposeFile": [
"../docker-compose.yml",
],
"service": "flutter",
"remoteUser": "root",
"remoteEnv": {
"QT_X11_NO_MITSHM": "1",
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/flutter/bin",
},
"settings": {
"terminal.integrated.shell.linux": null
},
"runArgs": [
"--privileged",
"-P",
],
"extensions": ["dart-code.flutter"],
"workspaceMount": "source=${localWorkspaceFolder}/workspace,target=/root/workspace,type=bind,consistency=delegated",
"workspaceFolder": "/root/workspace"
}
Host OSがLinuxの場合
Linux OSの場合、OpenGLでDRM (DRI) をDockerコンテナ内のFlutterアプリが利用できるように、/dev/dri
をbind-mountします。
version: "3"
services:
flutter:
image: flutter-docker/ubuntu:latest
working_dir: /root/workspace
command: sleep infinity
environment:
- HOME=/root
- no_proxy=127.0.0.1,localhost
volumes:
- ~/.gitconfig:/home/root/.gitconfig
- ./:/root/workspace
- /tmp/.X11-unix:/tmp/.X11-unix
devices:
- /dev/dri:/dev/dri
network_mode: "host"
extra_hosts:
- flutter:127.0.1.1
Host OSのDISPLAY
環境変数を引継ぎます。
{
"name": "Flutter docker",
"dockerComposeFile": [
"../docker-compose.yml",
],
"service": "flutter",
"remoteUser": "root",
"remoteEnv": {
"QT_X11_NO_MITSHM": "1",
"DISPLAY": "${localEnv:DISPLAY}",
"XAUTHORITY": "/tmp/.X11-unix",
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/flutter/bin",
},
"settings": {
"terminal.integrated.shell.linux": null
},
"runArgs": [
"--privileged",
"-P",
],
"extensions": ["dart-code.flutter"],
"workspaceMount": "source=${localWorkspaceFolder}/workspace,target=/root/workspace,type=bind,consistency=delegated",
"workspaceFolder": "/root/workspace"
}
8. Flutter in Dockerの実行
VSCode立ち上げ
docker-compose.yml
が存在するディレクトリでVSCodeを立ち上げます。
$ code .
VSCode Remote Containerのオープン
ウインドウ左下の><
の部分をクリックもしくは、shift+alt+p
でコマンドパレットを開き、Remote-containers: Open Folder in Container...
を選択します。
VSCodeウインドウ下部にターミナルが開きます。このターミナル操作対象は作成したDockerコンテナイメージ (flutter-docker/ubuntu:latest) です。
Flutterサンプルアプリのプロジェクト作成
ここからVSCodeのターミナル (Dockerコンテナ) で以下のコマンドを実行し、Flutterサンプルアプリを実行します。
# flutter config --enable-linux-desktop
# flutter config --enable-web
# mkdir sample
# cd sample
# flutter create .
Flutterサンプルアプリの実行
サンプルアプリ for Linux Desktop
# flutter run -d linux
コマンドを実行する以外には、VSCodeでdartソースコードを開いて、GUI操作でもアプリ実行やブレークポイントを利用したデバッグ等が可能です。
サンプルアプリ for Web
対応中なので少々お待ちを。。
# flutter run -d chrome