Docker コンテナの OS を確認する方法

いきなりまとめ

ホストマシン上で次のコマンドを実行して出力されるメッセージを見る。

$ docker run --rm (調べたいDockerイメージ) sh -c "cat /etc/*-release"

背景

Dockerfile を書くときに RUNCMD コマンドで叩ける命令はベースとしている OS イメージに依存する。しかし、何の OS をベースとしているのかパッと見ただけでは分からない。 Dockerhub とかみれば分かることも多いが。

自分で調べる素朴な方法として、Dockerfile の FROM に指定されているベースイメージをたどっていき、OS のイメージ(debian とか alpine とか)に到達するまで繰り返すやり方がある。これは面倒くさいのでやりたくない。

次のアイデアといえば、調べたいコンテナを起動して中に入って OS の情報を得るやり方である。ただし、シェルを起動するコマンドが OS に依存する問題がある。Alpine Linux では bash が使えないので docker run -it (コンテナイメージ) bash とか叩くと Error: Cannot find module '/bash' とかエラーが出る。もう少しスマートにやりたい。

コンテナの OS の調べ方

だいたいの Linux OS では /etc/os-release というファイルに OS の情報が載っている。コンテナ内にあるこのファイルを覗きたい。ただし、centos では代わりに /etc/redhat-release を見るべきらしい。

そして、Dockerfile のベースイメージが FROM scratch でもない限りは sh コマンドは叩けるだろう。ってことで以下のコマンドをホストマシンで叩けばよい。

$ docker run --rm (調べたいDockerイメージ) sh -c "cat /etc/*-release"

ここで --rm オプションは、コンテナの実行が終了したときに、そのコンテナを削除するために指定している。

実行の例

上記のコマンドをいくつかの Docker イメージに対して実行して OS を調べてみる。

node:15

Docker の node:15 イメージで使われる OS を調べてみよう。

$ docker run --rm node:15 sh -c "cat /etc/*-release"
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
VERSION_CODENAME=stretch
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

ふむふむ。Debian らしい。

node:alpine3.13

$ docker run --rm node:alpine3.13 sh -c "cat /etc/*-release"
3.13.2
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.13.2
PRETTY_NAME="Alpine Linux v3.13"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"

名前の通りもちろん Alpine Linux。シェルを起動したいときは ash を使おう。

golang:1.14

$ docker run --rm golang:1.14 sh -c "cat /etc/*-release"
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

これも Debian

mongo:latest

$ docker run --rm mongo sh -c "cat /etc/*-release"
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.5 LTS"
NAME="Ubuntu"
VERSION="18.04.5 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.5 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

これは Ubuntu

hello-world:latest

$ docker run --rm hello-world sh -c "cat /etc/*-release"
docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: 
starting container process caused: exec: "sh": executable file not found in $PATH: unknown.

sh コマンドが見つからないってエラーメッセージが出る。これは FROM scratch している Docker イメージだと思えばよさそう。Dockerfile の FROM にこのイメージを指定しても RUN とか CMD で何のコマンドも叩けない。

参考

python - determine OS distribution of a docker image - Stack Overflow

os-release