Debian (slim)ベースのDocker imageにgit contribを導入する


2025年 05月 15日

SI部のr_maedaです。

先日、Debian slimベースのカスタムDockerイメージを作る際に、git contribのソフトウェアをインストールしようとしたところ、少し苦労した部分がありました。

具体的に何が起きていたのか、またそれを解決するために何をする必要があったのかを、git contribとして配布されている diff-highlight をDebian 12 bookwormにインストールする手順を紹介しながら解説していきます。

git contribとは?

gitパッケージにバンドルされている、「gitのコア機能とは関係ないが、Gitの利用者にとっては便利な周辺ソフトウェア」を指します。

それぞれのcontribは、gitリポジトリの以下のディレクトリで管理されています。

https://github.com/git/git/tree/master/contrib

Debianへのdiff-highlightのインストール(非Docker環境)

非Docker環境の場合、diff-highlight のインストールは簡単です。

  1. apt-get install git を実行すると /usr/share/doc/git/contrib/ ディレクトリが作成されます
  2. 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

Debianへのdiff-highlightのインストール
(Docker環境、非slimイメージ)

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へのdiff-highlightのインストール
(Docker環境、slimイメージ、実験版)

次に、ベースイメージを 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.pmMakefilediff-highlight.perl は存在しませんでした🤔

なぜdiff-highlightのソースコードが展開されないのか

色々と調べてみた結果、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/*

# (後略)

Debianへのdiff-highlightのインストール
(Docker環境、slimイメージ、修正版)

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-excludepath-include の適用順が期待通りにならないことがあります。

ソースや仕様書は見つけられていませんが、簡単に実験してみた限りでは dpkg.cfg.d 以下のファイルは「ファイル名のアルファベット昇順」で読み込まれるようです。

今回追加する設定は path-exclude /usr/share/doc/* よりも後に適用する必要があるため、作成するファイル名には docker 以降に読み込まれる名前を指定してください。

参考

< 前の記事へ 次の記事へ >