この記事はAndroidのCI環境をCircleCIからWerckerにした話に関連した投稿です。
概要
Wercker(ワーカー)で使用するDockerイメージの作成。Androidのビルドに必要な環境をDockerfileで記述しイメージを作成する。
2017/6/9追記
以下で解説している「Dockerを利用する準備」では、docker-toolboxを利用しdocker-machineを起動してDockerを利用していますが、現在ではDocker for Macを利用するのが一番簡単にDockerを利用する環境を構築できます。
こちらからインストールするか以下のコマンドでインストールします。
brew cask install docker
インストールが完了後、docker-machineの設定を行うこと無くDockerを利用可能になります。詳しくは以下のリンクを御覧ください。
Dockerを利用する準備
Dockerはlibcontainer(バージョン0.9からLXCより移行)を使用してコンテナ型仮想化を行うためLinux上でしか動作しない。Mac上でDockerを動かすためには、Docker Machineを使いDocker Engineがインストールされた仮想環境を用意する必要がある。Docker Machineはdocker-machine
コマンドを使いDocker Engineがインストールされた仮想環境(Dockerホスト)を管理できる。
https://docs.docker.com/machine/overview/
一般的にDockerという場合Docker Engineを指す。DockerコンテナはDocker Engine上で動作し、Docker EngineはDocker daemonからなる。Docker daemonはREST APIのインターフェースを持ち、Docker Client(CLIなど)はREST API wrapperを介してDocker daemonとやりとりをする。
https://www.docker.com/products/docker-engine
Docker EngineはCLIからのdocker
コマンドを受け付け、docker run <image>
の実行や、docker ps
でのコンテナリストの表示、docker images
によるimageリストの表示などを行える。
Docker Machineのインストール
以下のドキュメントを参考にDocker Toolboxをインストールすると必要なものが全て用意される。
Homebrewを利用する場合
また、Homebrewを利用しているのであれば以下のコマンドでdockertoolboxインストールし、LaunchpadからDocker Quickstart Terminalを実行することでインストールできる。参考
$ brew cask install docker-toolbox
確認
以下のコマンドを叩きバージョンが表示されればOK。
$ docker-machine version
MacローカルにDockerホストを起動
- ターミナルを開く
-
docker-machine ls
コマンドで利用可能なVMを表示、VMが無ければ次のステップで作成する -
docker-machine create --driver virtualbox default
を実行
- --driverでvirtualboxを指定し、最後の引数がVMの名前になる
-
docker-machine ls
でVMが作られたことを確認 -
作成したVMについて
env
コマンドを実行- 作成したVMとDockerコマンドがやりとりするために必要な情報が表示されるので、exportを手動で実行するか
eval "$(docker-machine env default)"
を実行する
$ docker-machine env default export DOCKER_TLS_VERIFY="1" export DOCKER_HOST="tcp://172.16.62.130:2376" export DOCKER_CERT_PATH="/Users/<yourusername>/.docker/machine/machines/default" export DOCKER_MACHINE_NAME="default" # Run this command to configure your shell: # eval "$(docker-machine env default)"
- 作成したVMとDockerコマンドがやりとりするために必要な情報が表示されるので、exportを手動で実行するか
VMが起動していない場合は、docker-machine start default
で起動しておく。
Dockerfileの作成
Dockerfileを作成していくが、Dockerfileを実行しながら書いていくのは大変なので一旦コンテナを立ち上げ手動で環境を構築する。この際使用したコマンドはメモしておく。
コンテナの起動
$ docker run -it ubuntu:16.04 sh
Dockerfileへコマンドをまとめる
環境を構築できたらメモしておいたコマンドをDockerfileにまとめる。
FROM ubuntu:16.04
MAINTAINER Ryosuke Horie
# Install sudo
RUN apt-get update \
&& apt-get -y install sudo \
&& useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo
# Install 32bit lib
RUN sudo apt-get -y install lib32stdc++6 lib32z1
# Install Java8
RUN apt-get install -y software-properties-common curl \
&& add-apt-repository -y ppa:openjdk-r/ppa \
&& apt-get update \
&& apt-get install -y openjdk-8-jdk
# Download Android SDK
RUN sudo apt-get -y install wget \
&& cd /usr/local \
&& wget http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz \
&& tar zxvf android-sdk_r24.4.1-linux.tgz \
&& rm -rf /usr/local/android-sdk_r24.4.1-linux.tgz
# Environment variables
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64
ENV ANDROID_HOME /usr/local/android-sdk-linux
ENV PATH $ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$PATH
# Update of Android SDK
RUN echo y | android update sdk --no-ui --all --filter "android-23,build-tools-23.0.3" \
&& echo y | android update sdk --no-ui --all --filter "extra-google-m2repository,extra-android-m2repository"
Dockerfileからイメージを作成
Dockerfileを作成したらbuildコマンドでイメージを作成する。
$ docker build -t horie1024/wercker-android-build:0.1 .
docker images
コマンドでimageが表示されればOK
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
horie1024/wercker-android-build 0.1 12e03f69297e About an hour ago 2.023 GB
imageからコンテナを作成する
docker run
コマンドを実行しコンテナを作成する。
$ docker run -it horie1024/wercker-android-build:0.1 /bin/bash
作成したコンテナで名前解決ができない場合--dns
オプションをつける。
$ docker run -it --dns=8.8.8.8 horie1024/wercker-android-build:0.1 /bin/bash
コンテナが使用するメモリを指定する場合は、-m
オプションを使用する。
$ docker run -it -m 4G --dns=8.8.8.8 horie1024/wercker-android-build:0.1 /bin/bash
-m
オプション、--oom-kill-disable
オプションを使用するとOOMが発生しなくなる。
参考:Docker run リファレンス#ユーザ・メモリの制限
Androidプロジェクトがビルドできるか試す
用意したサンプルプロジェクトをcloneしビルドしてみる。
$ git clone https://github.com/horie1024/WerckerAndroidSample.git && cd WerckerAndroidSample
$ ./gradlew assembleDebug
Incremental java compilation is an incubating feature.
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:checkDebugManifest
:app:preReleaseBuild UP-TO-DATE
:app:prepareComAndroidSupportAnimatedVectorDrawable2330Library UP-TO-DATE
:app:prepareComAndroidSupportAppcompatV72330Library UP-TO-DATE
:app:prepareComAndroidSupportSupportV42330Library UP-TO-DATE
:app:prepareComAndroidSupportSupportVectorDrawable2330Library UP-TO-DATE
:app:prepareDebugDependencies
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:processDebugManifest UP-TO-DATE
:app:processDebugResources UP-TO-DATE
:app:generateDebugSources UP-TO-DATE
:app:compileDebugJavaWithJavac UP-TO-DATE
:app:compileDebugNdk UP-TO-DATE
:app:compileDebugSources UP-TO-DATE
:app:prePackageMarkerForDebug
:app:transformClassesWithDexForDebug UP-TO-DATE
:app:mergeDebugJniLibFolders UP-TO-DATE
:app:transformNative_libsWithMergeJniLibsForDebug UP-TO-DATE
:app:processDebugJavaRes UP-TO-DATE
:app:transformResourcesWithMergeJavaResForDebug UP-TO-DATE
:app:validateDebugSigning
:app:packageDebug UP-TO-DATE
:app:zipalignDebug UP-TO-DATE
:app:assembleDebug UP-TO-DATE
BUILD SUCCESSFUL
問題無くビルドができた。
イメージの公開についての注意
作成したイメージをDockerHubなどに登録するとdocker pull
することで様々な環境でイメージを利用できるようになりますが、Android SDKを含むDockerイメージをpublicで公開すると再配布としてAndroid SDKのライセンス違反となります。DockerHubのprivate repository、もしくはQuay.ioなどのDocker registryサービスのprivate repositoryの利用を検討してください。
Werckerからprivate repositoryを使用する方法は以下にまとめました。
参考資料
- 公開用DockerイメージにAndroid SDKを含めるのはライセンス違反という話
- https://docs.docker.com/machine/overview/
- https://docs.docker.com/machine/get-started/
- https://www.docker.com/products/docker-engine
- http://www.slideshare.net/yuichi110/docker-introduction-42455180
- http://stackoverflow.com/questions/22701405/aapt-ioexception-error-2-no-such-file-or-directory-why-cant-i-build-my-grad