シェルでDockerHubリポジトリからイメージとタグを取得する方法

Docker

はじめに

DockerHubのようなイメージリポジトリからイメージを検索する際には docker search コマンドが利用できます。
このコマンドで「イメージ名」は検索できるのですが「タグ」が検索できず、例えば「MySQLイメージの5.6バージョンのタグを知りたいんだけど、どうしよう?」となることがよくあります。

コマンドラインでなんとかしてみます。

検証環境

$ uname -moi
x86_64 MacBookPro11,4 Darwin

$ bash -version | head -n 1
GNU bash, バージョン 5.0.7(1)-release (x86_64-apple-darwin18.5.0)

$ docker --version
Docker version 18.09.2, build 6247962

$ jq --version
jq-1.6

docker search コマンドとは

Docker Hubでコンテナイメージをを検索するためのコマンドです。

例えば、 "mysql" 用のコンテナイメージを検索する場合には以下のようなコマンドを実行します。

$ docker search mysql
NAME                 DESCRIPTION                                     STARS  FFICIAL  AUTOMATED
mysql                MySQL is a widely used, open-source relation…   8417  [OK]
mariadb              MariaDB is a community-developed fork of MyS…   2895  [OK]
mysql/mysql-server   Optimized MySQL Server Docker images. Create…   624            [OK]
percona              Percona Server is a fork of the MySQL relati…   440   [OK]
centurylink/mysql    Image containing mysql. Optimized to be link…   60             [OK]
...

ラベルを見ると分かる通り、1列目にイメージ名が出力されています。

3番目、5番目のイメージは / で区切られた名前となっています。
/ の左は「ユーザ名」を表し右は「イメージ名」となっています。(これにより同一イメージ名を複数のユーザが利用しても競合しないようになっています。)

ちなみに、1番上のイメージはMySQLイメージ、2番目のイメージはMariaDBイメージであり、所有者はDocker公式の library という特殊なユーザです。
library が所有者の場合にはこれが省略されます。

以下の2つのコマンドは同じイメージを指しています。

$ docker run centos echo 'hello'
hello

$ docker run library/centos echo 'hello'
hello

イメージ名を指定してタグを取得するコマンド

早速タグ名を出力してみたいと思います。
公式に提供されているWebのAPIをコールすることで取得できます。

jq コマンドがインストールされている場合は楽です。

# 対象のイメージ名を設定
$ DOCKER_IMAGE=library/mysql

# コマンドを実行
$ curl \
  --silent "https://registry.hub.docker.com/v2/repositories/${DOCKER_IMAGE}/tags/" \
  | jq -r '."results"[]["name"]'

8.0.17
5.7.27
5.6.45
latest
8.0.16
8.0
8
5.7.26
5.7
5.6.44

jq コマンドがインストールされていない場合は grepsed でがんばります。

# 対象のイメージ名を設定
$ DOCKER_IMAGE=library/mysql

# grep -o でタグ名部分( "name": "..." )を抽出し、sedで不要部分を取り除く
$ curl \
  --silent "https://registry.hub.docker.com/v2/repositories/${DOCKER_IMAGE}/tags/" \
  | grep -o '"name": "[^"]\+"' \
  | sed 's/"$//; s/^.*"//'
8.0.17
5.7.27
5.6.45
latest
8.0.16
8.0
8
5.7.26
5.7
5.6.44

実際にタグを使用して起動できるか確認してみます。
タグは「イメージ名」後方に ":<タグ名>" の形式で文字列を付与することで指定できます。

# 初回は時間がかかる
$ docker run mysql:5.6.44 mysql --version
Unable to find image 'mysql:5.6.44' locally
5.6.44: Pulling from library/mysql
0a4690c5d889: Downloading  10.79MB/22.49MB
0a4690c5d889: Pull complete
98aa2fc6cbeb: Pull complete
0777e6eb0e6f: Pull complete
2464189c041c: Pull complete
b45df9dc827d: Pull complete
8f57052b58bf: Pull complete
ee774b34419e: Pull complete
bcb6c29a9771: Pull complete
f5eace967cb6: Pull complete
fe457a2a894d: Pull complete
a3266082cf3b: Pull complete
Digest: sha256:02b3ddb41d6e5d48d24aa8e59e1cd5870ddaca8ba7cdedf6602f7e6266240d64
Status: Downloaded newer image for mysql:5.6.44
mysql  Ver 14.14 Distrib 5.6.44, for Linux (x86_64) using  EditLine wrapper

# 2回目以降は早い
$ docker run mysql:5.6.44 mysql --version
mysql  Ver 14.14 Distrib 5.6.44, for Linux (x86_64) using  EditLine wrapper

# こちらの形式でイメージ名を指定しても同じ
$ docker run library/mysql:5.6.44 mysql --version
mysql  Ver 14.14 Distrib 5.6.44, for Linux (x86_64) using  EditLine wrapper

ひとこと

簡単なスクリプトだけど、Github / Dockerhub で公開しました。

Docker