Alpine LinuxでDockerコンテナ開発を加速する
ども、大瀧です。 Docker公式のベースイメージをAlpine LinuxにするPRによって、にわかにAlpine Linuxへの注目が集まっていますね。
いつか来るかも知れない(笑)Alpine Linux必須の時代に備えるべく、DockerでAlpine Linuxをどう扱っていくのかまとめてみました。
Alpine Linux概要
Alpine Linuxは、軽量なLinuxディストリビューションの一つです。最新バージョンは、3.3(2016/02/12現在)です。特にDocker向けというわけではないのですが、ベースイメージのフットプリントのサイズが非常に小さいことと、独自のパッケージ管理システムAPKがDockerfileの記法とマッチすることからDocker界隈で注目されているようです。
ベースDockerイメージはDocker公式版とGliderLabs版の2種類
現在利用できるAlpine LinuxのDockerベースイメージには、プレフィックス名なしのDocker公式版alpine
とGliderLabs版のgliderlabs/alpine
の2種類があります。ドキュメントによると、差異は以下2点とのことです。
- AlpineのパッケージミラーがFastly CDNでホストされ、世界中からスピーディーにインストールを実行できる。
apk-install
スクリプトが利用できる(後述)
試しに以下のDockerfile
でどれくらい時間差が出るか、検証してみました。
FROM alpine:3.3 # 2回目はgliderlabs/alpine:3.3に変更 RUN apk --no-cache add nodejs
$ time docker build -t takipone/alpine-node . Sending build context to Docker daemon 2.048 kB Step 1 : FROM alpine:3.3 ---> 14f89d0e6257 Step 2 : RUN apk --no-cache add nodejs ---> Running in 05e174d8076b fetch http://dl-4.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz fetch http://dl-4.alpinelinux.org/alpine/v3.3/community/x86_64/APKINDEX.tar.gz (1/4) Installing libgcc (5.3.0-r0) (2/4) Installing libstdc++ (5.3.0-r0) (3/4) Installing libuv (1.7.5-r0) (4/4) Installing nodejs (4.2.4-r1) Executing busybox-1.24.1-r7.trigger OK: 29 MiB in 15 packages ---> f66fb1d769d8 Removing intermediate container 05e174d8076b Successfully built f66fb1d769d8 real 1m56.365s user 0m0.023s sys 0m0.026s $
$ time docker build -t takipone/alpine-node . Sending build context to Docker daemon 2.048 kB Step 1 : FROM gliderlabs/alpine:3.3 ---> 169fc2bfcef7 Step 2 : RUN apk --no-cache add nodejs ---> Running in 4dabb895e0b1 fetch http://alpine.gliderlabs.com/alpine/v3.3/main/x86_64/APKINDEX.tar.gz fetch http://alpine.gliderlabs.com/alpine/v3.3/community/x86_64/APKINDEX.tar.gz (1/4) Installing libgcc (5.3.0-r0) (2/4) Installing libstdc++ (5.3.0-r0) (3/4) Installing libuv (1.7.5-r0) (4/4) Installing nodejs (4.2.4-r1) Executing busybox-1.24.1-r7.trigger OK: 29 MiB in 15 packages ---> d0efae9d2278 Removing intermediate container 4dabb895e0b1 Successfully built d0efae9d2278 real 0m7.301s user 0m0.018s sys 0m0.011s $
公式版のリポジトリdl-4.alpinelinux.org
は米国南部にあるようで、日本からのアクセスだとかなり差が出ました。特別な理由がない限り、GliderLabs版をお奨めします。
なお、差が出るのはあくまでパッケージリポジトリへのアクセスです。docker pull
でイメージをダウンロードする場合はどちらも同じDocker Hubからになるので速度は変わりません。といっても5MB程度しかないので、どちらにしろあっという間にベースイメージをPullすることができ、快適です。
差し当たっての注意点はパッケージマネージャとDNS
Dockerfile
を作成するにあたり、やはりディストリビューションのお作法を理解しておく必要があります。
Alpine Linuxは多くのディストリビューションと同じく、バイナリパッケージを検索/ダウンロードするパッケージマネージャ
を利用します。パッケージは以下のサイトで検索することができます。
ソースからプログラムをビルドするのであれば、ヘッダファイルを含む<パッケージ名>-dev
パッケージ、特に標準ライブラリのヘッダファイルを含むmusl-dev
パッケージを憶えておきましょう。ベースイメージにはそれらのパッケージが含まれていないので、何も考えずにdocker build
すると以下のエラーに出くわすことうけあいです。
Release/obj/gen/sqlite-autoconf-3090100/sqlite3.c:9457:19: fatal error: stdio.h: No such file or directory
メジャーどころのパッケージは一通り押さえている感じがしましたが、パッケージ名の規則は特にどのディストリビューションに合わせているわけでもなさそうです。他のディストリビューションのDockerfileからAlpineベースに移行する場合、パッケージ名の照合は数が多いと骨の折れる作業かもしれません。今回試した中では、Ubuntuのgpg
パッケージがAlpineではgnupg
パッケージが対応していました。
また、ドキュメントにあるようにresolv.conf
のdomain
行とsearch
行を読まないので、クラスタ構成などでショートホスト名を前提に組んでいる場合など注意が必要です。
パッケージマネージャのオプションがDockerfileに向いている
パッケージマネージャAPKのオプションは、元々キャッシュをローカルに持たないように設計されているためDockerイメージと相性が良いです。いくつかバリエーションがありますが、キャッシュを残さない--no-cache
オプションとパッケージをグループ化する--virtual
オプションを押さえておけば良いでしょう。GliderLabs版に含まれるapk-install
スクリプト(apk --no-cache add
と同等)が、最もシンプルに書ける記法だと思います。
Dockerfileの例
ちなみに、オプションを指定しないapk add
ではリポジトリに問い合わせに行かないのでパッケージが見つからずエラーになるので注意しましょう(従来のイメージでapt-get update
を実行しないときと同等)。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE takipone/alpine-ghost latest 3b7b8caa2eef 5 seconds ago 171.1 MB takipone/ghost 0.7.6 849f9983543b 2 days ago 352 MB gliderlabs/alpine 3.3 169fc2bfcef7 3 weeks ago 4.794 MB node 4.2-slim 1716606794de 4 weeks ago 205.3 MB
上の2つがアプリのインストール済みイメージ、下2つがその前のベースイメージです。奇数行がAlpineベース、偶数行がUbuntuベースです。Alpineのベースイメージが非常に小さいことがわかる反面、今回のアプリはNode.jsなのでアプリの増分がそのままベースに乗っかる形になっていること読み取れます。
まとめ
Alpine LinuxのイメージをDockerでどう扱うかをご紹介しました。ベースイメージの小ささはdocker pull
をはじめとするDockerイメージのオペレーションにかかる時間を劇的に短くするので、体感すると結構感動しますよ。
徐々に実績も増えていくと思いますので、注目していきましょう!
ひとまず、個人のブログを実行するDockerイメージはAlpineベースに移行済みで、ここ数日は安定稼働しているようです。