それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

dockerfileでAPTプロキシとシェル変数を渡す例。

docker build で apt installを高速化

docker build で毎回ダウンロードが公式レポジトリから行われるのが、心苦しい。

無駄な通信が発生している。そして何より遅い

ビルド例

export APT_HTTP_PROXY=http://192.168.2.21:3142 
docker build --build-arg APT_HTTP_PROXY=${APT_HTTP_PROXY} -t sample .

Dockerfileの例

dockerfile で次のように記述すればいい。

FROM ubuntu:20.04
ENV DEBCONF_NOWARNINGS=yes
ARG APT_HTTP_PROXY
ENV APT_HTTP_PROXY=${APT_HTTP_PROXY}
RUN echo "Apt Config" && \
echo "APT::Install-Suggests 0;\nAPT::Install-Recommends 0;"  \
  |   tee /etc/apt/apt.conf.d/00-no-install-recommends && \
echo "path-exclude=/usr/share/locale/*\npath-exclude=/usr/share/man/*\npath-exclude=/usr/share/doc/*\n" \
    | tee  /etc/dpkg/dpkg.cfg.d/01-nodoc && \
echo "Acquire::HTTP::Proxy \"${APT_HTTP_PROXY}\";" >> /etc/apt/apt.conf.d/01proxy && \
echo 'Acquire::HTTPS::Proxy "false";' >> /etc/apt/apt.conf.d/01proxy && \
apt-get update && \
apt-get upgrade -y

とくにポイントになるのは、次の二行

echo "Acquire::HTTP::Proxy \"${APT_HTTP_PROXY}\";" >> /etc/apt/apt.conf.d/01proxy && \
echo 'Acquire::HTTPS::Proxy "false";' >> /etc/apt/apt.conf.d/01proxy && \

また、プロキシ設定をビルド時変数で渡す箇所を利用して、再利用性を高める。

ARG APT_HTTP_PROXY
ENV APT_HTTP_PROXY=${APT_HTTP_PROXY}

dockerfile のコツ

docker build を実行するシェルから変数を渡すのに、--build-arg が使える。

Dockerfileでは、ビルド変数を受け取るARG $NAMEがある。 ARG $NAME で受け取った変数をビルド用変数としてENV NAME=$NAMEで展開する。 RUN cmdENV 変数を使う。

このように書いておけば、Dockerfile にビルド時の変数を使える。

そして、ビルド時に変数を渡す

docker build --build-arg APT_HTTP_PROXY=${APT_HTTP_PROXY}

APTプロキシを使うコツ

プロキシ自体はdocker run sameersbn/apt-cacher-ng で起動できる。

https:// のレポジトリは、httpを強制すれば簡単にプロキシが可能

sed -e 's|https:|http:|' -i /etc/apt/sources.list.d/docker.list

apt update は http でプロキシつながるのは次のような動作背景にある。

  • apt update で、http://apt.example.tld/ へ プロキシ経由でアクセスする。
    • プロキシはhttpで取得を試行する。
    • オリジンサーバーがhttp->https へアップグレードをかける。
    • プロキシがhttps でコンテンツを取得
    • プロキシは apt 結果として httpsの取得結果を返す
  • apt update の結果が取得される。

過去の資料

過去の関連資料です。

apt インストールは「何度も実行する」ために存在するわけではない。通信はプロキシでキャッシュするしか無い。

 またaptのRUNより手前を書換えるとdockerfileのキャッシュがうまく効かないんですよね。とくにRUNを1回で済ませようとすると、毎回aptが実行されて、数秒の待ち時間が必要。その待ち時間が10秒でも回数が30回を超えてくると流石に面倒なです。