AndroidやScala/sbtも日進月歩なので、変化追い易くなればと思い Docker で開発環境を作ってみた。
今回はDockerの勉強を兼ねて Ubuntu 14.04 ベースで Android SDK + sbt のイメージを作ったので、これを使ってScalaでのAndroid開発の環境を準備した。Dockerとの役割分担の方針として:
- sbtでのビルドやAndroidデバイスの定型操作などCUI操作はDockerのコンテナ上でやる
- 実機USB接続やエミュレータ実行、IDE起動はオーバーヘッドの少ないホスト機でやる
- 両者の通信は、adbサーバの5037番ポートをDockerコンテナからホスト機にSSHフォワードして行う
ことにした。
(1) Dockerのセットアップ
ホスト機にMacを使っているので boot2docker を入れる。
この記事などを参考にした。
$ brew install boot2docker
$ boot2docker init
$ boot2docker up
(2) Dockerイメージの動作確認
下のコマンドで、Android SDK + sbt + sshd が入ったイメージ ( ikuo/android-sbt ) からコンテナが起動する。初回はイメージのダウンロードで小一時間かかる。
$ docker run -it --rm -p 7022:22 ikuo/android-sbt:0.2 "`cat ~/.ssh/id_rsa.pub`"
最後の引数にある id_rsa.pub
は、コンテナにssh接続する時に使う鍵ファイル。
動作確認なので --rm
をつけて終了時にコンテナを消すようにしてある。
-p 7022:22
でコンテナの22番ポートにホスト機(boot2dockerの場合はboot2docker-vm)の7022番をフォワードする。
boot2dockerの場合はさらにこの記事 などを参考に、ホスト機の7022番をboot2docer-vmの7022番にフォワードさせておく:
# Macでoot2docker 使っている場合の追加手順
$ VBoxManage controlvm "boot2docker-vm" natpf1 "ssh to android-sbt,tcp,127.0.0.1,7022,,7022"
コンテナが起動したらホスト機からコンテナに下のようにSSH接続して、adbサーバが使う5037番をホスト機にフォワードしておく。adbのclient/server構成やポート番号などはこちらを参考にした。
$ ssh ubuntu@localhost -p 7022 -R 5037:localhost:5037 -Nv
ホスト機で、 adb start-server
してから適当なエミュレータ起動や実機接続をしておくと、コンテナ上のadbコマンドからホスト機のAndroidデバイスが見えるようになる。
ubuntu@xxxxxxxxxx:~$ adb devices
List of devices attached
999673041154999 device
※ ホスト機でadbサーバが起動していない場合は error: protocol fault (no status)
のような表示になる。
(3) android-sdk-plugin でのビルド
最近自分はsbtでのAndroidプロジェクトのビルドにandroid-sdk-pluginを使っているので、先のDockerのイメージも android-sdk-plugin に必なものだけを含めた。sbt-android plugin との違いはこちらにあったりする。
今回は既に android-sdk-plugin ベースのプロジェクトが手元にあったので、git cloneした後に下のように android update project を実行して Android SDK のパスを設定した。
ubuntu@...:~/work/myproject$ android update project -p . -t android-19
ubuntu@...:~/work/myproject$ git checkout proguard-project.txt
※ proguardの設定が上書きされたのでgitでリセット(2行目)
その後sbtでapkをビルドしてrun
すると、ホスト機上のエミュレータや実機端末でアプリが無事に起動した。
ubuntu@...:~/work/myproject$ sbt android:package
ubuntu@...:~/work/myproject$ sbt run
動作確認に使ったアプリはこちら。
(4) IDEでのファイル編集
レイアウトファイルなどはホスト機の IDE (IntelliJ IDEA) でレンダリング確認しながら編集したいので、こちらの手順を参考にファイル共有をセットアップした。
$ docker run -itd -v /data --name my-data busybox /bin/sh
$ docker run --rm -v /usr/local/bin/docker:/docker -v /var/run/docker.sock:/docker.sock svendowideit/samba my-data
$ boot2docker ip
192.168.59.103
上のコマンドは svendowideit/samba というイメージをもとに my-data
という名前でファイル共有用のコンテナを起動するもの。my-dataコンテナは間違って消してしまわないように-itd
オプションをつけてシェルをバックグラウンドで起動してある。
\192.168.59.103\data に共有フォルダができるので、MacならここにFinderで「サーバに接続」すると /Volumes/data にCLIでファイルを読み書きできるようになる。ここにコンテナからアクセスするには起動時に--volumes-from my-data
をつけて /data を読み書きする。
ということで(2)のコンテナ起動にこのオプションをつけると、android-sbtのコンテナ起動コマンドは下のようになった:
$ docker run -it --rm -p 7022:22 --volumes-from my-data ikuo/android-sbt:0.2 "`cat ~/.ssh/id_rsa.pub`"
ubuntu@...:~$ sudo chown -R ubuntu /data
後は /data 以下にプロジェクトファイルをgit cloneするなりして編集&ビルドすればOK。