UbuntuからAlpineにイメージを移行して容量を減らす例

# 概要

Docker のベース・イメージを Ubuntu から Alpine Linux に移行し、Docker イメージの容量を削減できた（141MB→3MB）。このイメージのビルド時、コマンドラインで扱う analog コマンドを make し、コマンドとして analog コンテナを使うイメージにする。以下は具体的な移行手順を記載。

![alpine.png](https://qiita-image-store.s3.amazonaws.com/0/13002/aa96d2f4-fe4f-7c13-87a9-f05cc2b03a3a.png)


# 動機

アクセス解析ツール Analog の Docker コンテナ対応作業を進めている。 `Ubuntu:14.04` イメージを元に作成していたが、容量が 141MB と大きかった。  `consul` の公式イメージが 10MB という小ささなのは `Alpine` イメージを使っているからではという仮説からスタート。検証のため、イメージを `Ubuntu` から `Alpine` に移行することにした。

# Dockerfile 移行時の考慮点

## パッケージ・マネージャ

Ubuntu では `apt` を使えたが、Alpine では使えない。 `apk` という Alpine Linux package management というパッケージ・マネージャを使う必要がある。

* https://wiki.alpinelinux.org/wiki/Alpine_Linux_package_management

* `apt-get update` に相当するコマンドは `apk update` 。これを実行しないと、パッケージ一覧情報を取得できない。
* `apt-get install <パッケージ名>` に相当するのは `apk add <パッケージ名>`
* `apt-get remove` に相当するのは `apk del <パッケージ名>`
 
なお、 update と install を同時に行うには `apk --update add <package>` という指定も可能。

イメージの容量を小さくするため、作業後は `apk del` の活用や、キャッシュを消す `apk cache clean` や `apk --no-cache add <package>` の組み合わせを活用できる。

その他の頻出オプションは、

* `apk search <package>` ... パッケージの検索
* `apk info <package>` ... パッケージ情報の表示

参考：https://wiki.alpinelinux.org/wiki/Alpine_Linux_package_management

## make 環境

素の Alpine では make 環境が入っていない。最低限必要な環境は、次のコマンドを実行。

```
# apk add make gcc g++
```


## bash

デフォルトのシェルは `/bin/sh` のため、 `Ctrl-p` などキーバインドを使えない。解決するには `bash` のパッケージを追加する。

```
# apk add bash
```


## タイムゾーン

デフォルトでは UTC のまま。変更するには `tzdata` パッケージをセットアップする必要がある。以下は JST-9 に設定する方法。

```
# apk --update add tzdata
# cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# apk del tzdata
```

参考：https://wiki.alpinelinux.org/wiki/Setting_the_timezone


# Dockerfile の書き換え

以下は初期の Ubuntu イメージを使う Dockerfile

```
FROM ubuntu:14.04

RUN mkdir -p /tmp/analog && \
    apt-get update && \
    apt-get install -y make gcc wget

RUN cd /tmp/analog && \
    wget -O analog-6.0.tar.gz ftp://ftp.naist.jp/pub/sunfreeware/SOURCES/analog-6.0.tar.gz && \
    tar xfz analog-6.0.tar.gz

RUN cd /tmp/analog/analog-6.0 && \
    make DEFS='-DLANGDIR=\"/opt/analog/lang/\"' && \
    mkdir -p /opt/analog && \
    cp -r lang /opt/analog/ && \
    mv ./analog /usr/bin/analog && \
    rm -rf /tmp/analog

COPY analog.cfg /opt/analog/analog.cfg

CMD ["+g/opt/analog/analog.cfg"]
ENTRYPOINT ["/usr/bin/analog","-G"]
```

これを `Ubuntu` から `Alpine` に向けてコマンドを書き換える。

差分情報
https://github.com/zembutsu/dockerize-analog/commit/b8ac2ebc16c2a8ff66836a2063c2394cbd94ae8a

この時点で容量は 141MB から 51MB に削減できた。

さらに、Docker のイメージ・レイヤを減らすため、3行あった `RUN` 命令を 1行にまとめることで、最終的なイメージ容量は 3MB まで削減出来た。

最終的な Dockerfile

```
FROM alpine:3.3

RUN mkdir -p /tmp/analog && \
    apk --no-cache add make gcc g++ && \
    cd /tmp/analog && \
    wget -O analog-6.0.tar.gz ftp://ftp.naist.jp/pub/sunfreeware/SOURCES/analog-6.0.tar.gz && \
    tar xfz analog-6.0.tar.gz && \
    cd /tmp/analog/analog-6.0 && \
    make DEFS='-DLANGDIR=\"/opt/analog/lang/\"' && \
    mkdir -p /opt/analog && \
    cp -r lang /opt/analog/ && \
    mv ./analog /usr/bin/analog && \
    rm -rf /tmp/analog && \
    apk del make gcc g++

COPY analog.cfg /opt/analog/analog.cfg

CMD ["+g/opt/analog/analog.cfg"]
ENTRYPOINT ["/usr/bin/analog","-G"]
```


----
こちらもあわせてどうぞ

Alpine Linux で軽量な Docker イメージを作る - Qiita
http://qiita.com/pottava/items/970d7b5cda565b995fe7