SI部のr_maedaです。
先日、Debian slimベースのカスタムDockerイメージを作る際に、git contribのソフトウェアをインストールしようとしたところ、少し苦労した部分がありました。
具体的に何が起きていたのか、またそれを解決するために何をする必要があったのかを、git contribとして配布されている diff-highlight
をDebian 12 bookwormにインストールする手順を紹介しながら解説していきます。
gitパッケージにバンドルされている、「gitのコア機能とは関係ないが、Gitの利用者にとっては便利な周辺ソフトウェア」を指します。
それぞれのcontribは、gitリポジトリの以下のディレクトリで管理されています。
非Docker環境の場合、diff-highlight
のインストールは簡単です。
apt-get install git
を実行すると /usr/share/doc/git/contrib/
ディレクトリが作成されますgit/contrib/diff-highlight
ディレクトリに移動し make
を実行、その生成物をPATHの通ったディレクトリに置くことで、diff-highlight
が利用可能になります
install
を使っていますが、シンボリックリンクを貼る方法でも良さそうですroot@vbox:/home/vboxuser# uname -a
Linux vbox 6.1.0-34-arm64 #1 SMP Debian 6.1.135-1 (2025-04-25) aarch64 GNU/Linux
root@vbox:/home/vboxuser# ls /usr/share/doc/git
ls: cannot access '/usr/share/doc/git': No such file or directory
root@vbox:/home/vboxuser# apt-get install -y git
(中略)
root@vbox:/home/vboxuser# ls /usr/share/doc/git/contrib/diff-highlight/
diff-highlight.perl DiffHighlight.pm Makefile README t
root@vbox:/home/vboxuser# cd /usr/share/doc/git/contrib/diff-highlight/
root@vbox:/usr/share/doc/git/contrib/diff-highlight# make && install -m 755 diff-highlight /usr/bin
Docker環境の場合も、非slimイメージであれば期待通り diff-highlight
のソースコードが展開されました。非Docker環境同様、make && install
することが可能です。
実験のために用意した Dockerfile
と、docker build
の実行ログは以下のとおりです。
# Dockerfile
FROM debian:bookworm
# この時点ではディレクトリがないため、lsコマンドの終了ステータスがnon-zeroになってしまう。
# 次のRUNに進めないのでtrueを付けて終了ステータスを上書きする
RUN ls /usr/share/doc/git; true
# build-essential, gitパッケージのインストール
# NOTE: build-essential - makeコマンドを入れるためのパッケージ
RUN apt-get update && apt-get install -y build-essential git
# diff-highlightのソースコードは展開されていますか?
RUN ls /usr/share/doc/git/contrib/diff-highlight
$ docker build --no-cache --progress=plain .
#0 building with "desktop-linux" instance using docker driver
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 190B done
#1 DONE 0.0s
#2 [internal] load metadata for docker.io/library/debian:bookworm
#2 DONE 0.7s
#3 [internal] load .dockerignore
#3 transferring context: 2B done
#3 DONE 0.0s
#4 [1/4] FROM docker.io/library/debian:bookworm@sha256:264982ff4d18000fa74540837e2c43ca5137a53a83f8f62c7b3803c0f0bdcd56
#4 CACHED
#5 [2/4] RUN ls /usr/share/doc/git; true
#5 0.095 ls: cannot access '/usr/share/doc/git': No such file or directory
#5 DONE 0.1s
#6 [3/4] RUN apt-get update && apt-get install -y build-essential git
# (中略)
#6 DONE 122.6s
#7 [4/4] RUN ls /usr/share/doc/git/contrib/diff-highlight
#7 0.127 DiffHighlight.pm
#7 0.127 Makefile
#7 0.127 README
#7 0.127 diff-highlight.perl
#7 0.127 t
#7 DONE 0.1s
#8 exporting to image
#8 exporting layers
#8 exporting layers 0.3s done
#8 writing image sha256:b1a0a68dae7662edc1cf8cfd2811f8461217829bddc297eb427e017fe514e7a0
#8 writing image sha256:b1a0a68dae7662edc1cf8cfd2811f8461217829bddc297eb427e017fe514e7a0 done
#8 DONE 0.3s
次に、ベースイメージを debian:bookworm-slim
に変更して、再度 docker build
を実行してみます。
# Dockerfile
FROM debian:bookworm-slim
RUN ls /usr/share/doc/git; true
RUN apt-get update && apt-get install -y build-essential git
# diff-highlightのソースコードは展開されていますか?
RUN ls /usr/share/doc/git/contrib/diff-highlight
$ docker build --no-cache --progress=plain .
#0 building with "desktop-linux" instance using docker driver
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 218B done
#1 DONE 0.0s
#2 [internal] load metadata for docker.io/library/debian:bookworm-slim
#2 DONE 0.7s
#3 [internal] load .dockerignore
#3 transferring context: 2B done
#3 DONE 0.0s
#4 [1/4] FROM docker.io/library/debian:bookworm-slim@sha256:4b50eb66f977b4062683ff434ef18ac191da862dbe966961bc11990cf5791a8d
#4 CACHED
#5 [2/4] RUN ls /usr/share/doc/git; true
#5 0.096 ls: cannot access '/usr/share/doc/git': No such file or directory
#5 DONE 0.1s
#6 [3/4] RUN apt-get update && apt-get install -y build-essential git
# (中略)
#6 DONE 26.0s
#7 [4/4] RUN ls /usr/share/doc/git/contrib/diff-highlight
#7 0.095 t
#7 DONE 0.1s
#8 exporting to image
#8 exporting layers
#8 exporting layers 0.3s done
#8 writing image sha256:c381feea4f68dc20944ac8f486d88fc2ccccd706583ea12bd78c9c9925daf3ad done
#8 DONE 0.3s
ベースイメージを変更したところ、ディレクトリまでは作成されましたが、 DiffHighlight.pm
や Makefile
、 diff-highlight.perl
は存在しませんでした🤔
色々と調べてみた結果、apt-get
の裏で動いている dpkg
の設定が関係していることがわかりました。
(※aptとdpkgの関係については、この記事では掘り下げません。)
dpkg
の設定ファイルが置かれているディレクトリの中を覗いてみると、slimイメージ側にのみ存在するファイルがあります。なお、同名のファイル docker-apt-speedup
は、中身も同じものでした。
$ docker run --rm -it debian:bookworm ls /etc/dpkg/dpkg.cfg.d/
docker-apt-speedup
$ docker run --rm -it debian:bookworm-slim ls /etc/dpkg/dpkg.cfg.d/
docker docker-apt-speedup
この追加されているファイルの中身を確認してみると、以下の設定が有効になっていました。
/usr/share/doc/*
にはファイルを展開しない
/usr/share/doc/*/copyright
と /usr/share/doc/kde/HTML/C/*
は除くこの設定さえ上書きしてあげれば、slimイメージの場合でもcontribがインストールできそうです。
$ docker run --rm -it debian:bookworm-slim cat /etc/dpkg/dpkg.cfg.d/docker
# This is the "slim" variant of the Debian base image.
# Many files which are normally unnecessary in containers are excluded,
# and this configuration file keeps them that way.
# dpkg -S '/usr/share/doc/*'
# adduser apt base-files base-passwd bash bsdutils coreutils dash debconf
# debian-archive-keyring debianutils diffutils dpkg e2fsprogs findutils
# gcc-12-base:arm64 gpgv grep gzip hostname init-system-helpers libacl1:arm64
# libapt-pkg6.0:arm64 libattr1:arm64 libaudit-common libaudit1:arm64
# libblkid1:arm64 libbz2-1.0:arm64 libc-bin libc6:arm64 libcap-ng0:arm64
# libcap2:arm64 libcom-err2:arm64 libcrypt1:arm64 libdb5.3:arm64
# libdebconfclient0:arm64 libext2fs2:arm64 libffi8:arm64 libgcc-s1:arm64
# libgcrypt20:arm64 libgmp10:arm64 libgnutls30:arm64 libgpg-error0:arm64
# libhogweed6:arm64 libidn2-0:arm64 liblz4-1:arm64 liblzma5:arm64
# libmd0:arm64 libmount1:arm64 libnettle8:arm64 libp11-kit0:arm64
# libpam-modules-bin libpam-modules:arm64 libpam-runtime libpam0g:arm64
# libpcre2-8-0:arm64 libseccomp2:arm64 libselinux1:arm64 libsemanage-common
# libsemanage2:arm64 libsepol2:arm64 libsmartcols1:arm64 libss2:arm64
# libstdc++6:arm64 libsystemd0:arm64 libtasn1-6:arm64 libtinfo6:arm64
# libudev1:arm64 libunistring2:arm64 libuuid1:arm64 libxxhash0:arm64
# libzstd1:arm64 login logsave mawk mount ncurses-base ncurses-bin passwd
# perl-base sed sysvinit-utils tar tzdata usr-is-merged util-linux
# util-linux-extra zlib1g:arm64
path-exclude /usr/share/doc/*
# (中略)
path-include /usr/share/doc/*/copyright
path-include /usr/share/doc/kde/HTML/C/*
# (後略)
Dockerfileを修正して、apt-get install
を実行する行の前に dpkg
の設定を変更する行を追加しました。
これでDebian slimベースのカスタムイメージでも diff-highlight
が使えるようになりました🎉
# Dockerfile
FROM debian:bookworm-slim
# diff-highlightのインストール準備
RUN echo "path-include /usr/share/doc/git/contrib/*" > /etc/dpkg/dpkg.cfg.d/git
# aptパッケージの導入
RUN apt-get update && apt-get install -y build-essential git
# diff-highlightのインストール
WORKDIR /usr/share/doc/git/contrib/diff-highlight
RUN make && install -m 755 diff-highlight /usr/bin
# (後略)
dpkg
の設定を変更している部分ですが、このときに作成するファイル名次第では、 path-exclude
と path-include
の適用順が期待通りにならないことがあります。
ソースや仕様書は見つけられていませんが、簡単に実験してみた限りでは dpkg.cfg.d
以下のファイルは「ファイル名のアルファベット昇順」で読み込まれるようです。
今回追加する設定は path-exclude /usr/share/doc/*
よりも後に適用する必要があるため、作成するファイル名には docker
以降に読み込まれる名前を指定してください。