LoginSignup
45
45

More than 5 years have passed since last update.

(Docker で) ローカルに APT のパッケージリポジトリキャッシュサーバ (apt-cacher-ng) を建てたら幸せになった。

Last updated at Posted at 2015-04-29

経緯

Dockerfile を何度も編集して apt-get install していると、
パッケージのダウンロードに大きく時間を喰ってると体感することが多かった。
特に既存のイメージを継承しない新しいイメージを作るときは、
git のような基本的なパッケージまで再取得する。

ミラーかキャッシュか

かといって apt-mirror を使ったフルミラーを建てるのもなかなか手軽ではないと感じたので、
apt-cacher-ng でキャッシュ用のプロキシサーバを建てることにした。

apt-cacher-ng では取得したパッケージのみをキャッシュするので、
apt-mirror のように導入初期に大量にパッケージを取得する必要はない。

自分の使用範囲では apt-cacher-ng の方が合っているので apt-cacher-ng を選択した。
きっと適切な使い分けがあるのだろうと思う。

Docker のサイトにもあった

実は Docker のサイトにも apt-cacher-ng 用の Docker イメージを作る方法が紹介されているので、
apt-cacher-ng プロキシサーバの構築も Docker で行った。なので構築は 1 分でできてしまった。

実際に使ってみたところ

プロキシ設定をする場合としない場合でそれぞれ docker build にかかる時間を time コマンドで記録した。
docker による cache を含まずに測定するため、 docker build --no-cache のように --no-cache オプションで実行した。
プロキシ設定をする場合は 2 回 build を実行し、キャッシュが有効になる 2 回目の build を記録とした。

プロキシ設定をする場合は、次のような行を Dockerfile の apt-get 等が始まる前に書き加える。

Dockerfile
RUN echo 'Acquire::http { Proxy "http://X.X.X.X:3142"; };' >> /etc/apt/apt.conf.d/01proxy

nginx だけをインストールしてみる場合

Dockerfile
RUN apt-get update && apt-get install -y nginx

プロキシなし

real    1m4.797s

プロキシあり

real    0m19.806s

だいたい所要時間が 1/3 になっている。嬉しい。

もっとてんこもりにインストールしてみる。

次のような、大量のパッケージもインストールしてみた。
手持ちの環境を作るシェルスクリプト等からいくつか抜き出してまとめたもの。
Docker の常識的な使い方ではこんなにたくさんインストールすることはあまりないはず。

Dockerfile
RUN apt-get update && \
    apt-get install -y \
        curl git vim tmux pv \
        build-essential make ccache \
        python-dev python-pip \
        nodejs nodejs-dev \
        libssl-dev \
        zlib1g-dev libbz2-dev \
        libreadline-dev libsqlite3-dev \
        gfortran libopenblas-dev liblapack-dev g++ \
        build-essential python3-tk tk-dev libpng12-dev \
        libzmq3-dev \
        freetds-dev freetds-bin tdsodbc \
        pandoc \
        r-base r-base-dev

プロキシなし

real    9m16.991s

プロキシあり

real    4m58.601s

こちらもすごく時間が短縮できた。 5 分減るのは大きい。

余談

以下は本題とは関係ないけど、一応触れておきたい話

DEBIAN_FRONTEND=nointeractive しよう

Ansible や Chef を使ってる人にもお馴染み。
Docker で apt-get する場合には

Dockerfile
ENV DEBIAN_FRONTEND noninteractive

をつける習慣を持つと良い。
シェルでの人間が操作する場合以外はつけた方がいい。インタラクティブな質問をしてこなくなる ([y/N] みたいな)
他にもたとえば ncurses が立ち上がるのを防いだり。

なぜ複数の RUN ではなく 1 つの RUN に複数行書く

イメージ差分は Dockerfile のステートメントごとに記録される。

記録されたあとにファイルの削除を行っても、イメージのサイズは減少しない。
RUN の最後でクリーンアップが可能ならした方がいい。

apt-get cleanrm を使って不要なファイルを消してしまう方が健全。
(追加で apt-get する予定がないなら、 /var/lib/apt/lists/* ごと削除する手もある。 )

Dockerfile
RUN apt-get update && \
    apt-get install -y git curl nginx && \
    apt-get clean &&
    rm -rf /tmp/* /var/tmp/*

タイトル

書いたあとで気がついた。
タイトルの「建てたら幸せになった」は、前に読んだ ↓ を無意識に継承してしまっていた。

45
45
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
45
45