docker-compose の最新リリースのバージョン確認（コマンドで最新バージョンを取得したい）

> `docker-compose` をインストールするのにバージョン指定が必要なため、最新バージョンを調べるのが面倒。

```bash:docker-composeのインストーラーの場合
version='1.24.0'
curl -L "https://github.com/docker/compose/releases/download/${version}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
```
```bash:docker-composeのDockerコンテナを使う場合
version='1.24.0'
docker pull docker/compose:${version}
```

> 🐒 2020/04/04 追記: [PR #7028](https://github.com/docker/compose/pull/7028) の 2019/11/19 のマージにて、`docker-compose` **v1.25.0 以降からは `latest` タグが使えるようになりました**。


## TL; DR（概要）

> API から最新バージョンを取得する

`docker-compose` は **Docker イメージに限らず、バイナリをダウンロードする場合でもバージョン指定が必須**です。（2020/04/04 現在、`latest` が指定可能になりました）

そのため、`docker-compose` の最新版を使いたい場合、バイナリの場合は GitHub、Docker コンテナ・イメージの場合は DockerHub の**リリース情報から最新バージョンを確認する必要があります**。

CI 系などで、最新バージョンでテストする必要がある場合は、スクリプトで各々の API から最新バージョンを取得します。

## API のエンドポイント

```text:GitHub（バイナリ）の最新リリースのエンドポイント
https://api.github.com/repos/docker/compose/releases/latest
```

```text:DockerHub（コンテナ）の最新リリースのエンドポイント
https://registry.hub.docker.com/v1/repositories/docker/compose/tags
```

## バージョンの取得例

### GitHub（バイナリのバージョン確認）
```bash:GitHub（バイナリ）の最新リリース・バージョンの取得
version=`curl -s https://api.github.com/repos/docker/compose/releases/latest | \
  grep tag_name | \
  sed -e 's/[^0-9\.]//g'`

echo $version
# 出力結果
# 1.24.0
```
- [オンラインで動作確認する](https://paiza.io/projects/umtDz4mChv7fq89WlQg6cA) | Ubuntu18.4 @ paiza.IO

### DockerHub（コンテナのバージョン確認）
```bash:DockerHub（コンテナ）の最新リリース・バージョンの取得
version=`curl -s https://registry.hub.docker.com/v1/repositories/docker/compose/tags | \
  sed -e 's/[][]//g' -e 's/"//g' -e 's/ //g' | \
  tr '}' '\n'  | \
  awk -F: '{print $3}' | \
  sed '/^$/d' | \
  tail -1`

echo $version
# 出力結果
# 1.9.0-rc4
```
- [オンラインで動作確認する](https://paiza.io/projects/jQVwqr82iK3o3NOTu8AzmA) | Ubuntu18.4 @ paiza.IO

## バージョン確認先情報

- Git リポジトリ（Docker Compose 公式）
    - [Docker Compose](https://github.com/docker/compose/) | by [Docker](https://github.com/docker) @ GitHub

- Docker イメージ・レジストリ（Docker Compose 公式）
    - [Docker Compose のリリース・タグ一覧](https://hub.docker.com/r/docker/compose/tags/) @ DockerHub
    - [Docker Compose](https://hub.docker.com/r/docker/compose) | by [Docker](https://hub.docker.com/u/docker) @ DockerHub

## TS; DR（詳細と所感）

- 「[But wait, there’s more!](https://medium.freecodecamp.org/the-easy-way-to-set-up-docker-on-a-raspberry-pi-7d24ced073ef#0a7d) | The easy way to set up Docker on a Raspberry Pi」@ Medium

ラズパイで Docker を動かすため[☝️この記事](https://medium.freecodecamp.org/the-easy-way-to-set-up-docker-on-a-raspberry-pi-7d24ced073ef)を読んだところ、**`docker-compose` すらも Docker で使いたい**と感銘を受け、どうせなら最新バージョンで試そうと思いました。

### 公式 `docker/compose` の `pull` 

一般的に最新バージョンのダウンロード（`pull`）は、イメージ名に `latest` タグを付けます。また、タグを付けない場合でも、自動的に `latest` を付加してレジストリ内を検索してくれます。

しかし、[DockerHub の「Docker Pull Command」に記載されている方法](https://hub.docker.com/r/docker/compose)でも取得できず、結論から言うと**バージョン番号のタグを明記しないとダメ**でした。

- `docker pull docker/compose` → <font color=red>NG</font>
- `docker pull docker/compose:latest` → <font color=red>NG</font>
- `docker pull docker/compose:1.23.2` → <font color=blue>OK</font>

```shell-session:バージョン番号の明記なし
$ docker pull docker/compose
Using default tag: latest
Error response from daemon: manifest for docker/compose:latest not found

$ docker pull docker/compose:latest
Error response from daemon: manifest for docker/compose:latest not found
```
```shell-session:バージョン番号の明記あり
$ docker pull docker/compose:1.23.2
1.23.2: Pulling from docker/compose
4fe2ade4980c: Pull complete 
658ccff8d4f1: Pull complete 
71166c3c8d42: Pull complete 
c246ed86dd59: Pull complete 
Digest: sha256:f6e4963cd17f709fb57f7cf0842e269ed6ba173c3490055b50c701a257feb860
Status: Downloaded newer image for docker/compose:1.23.2
```

#### バージョン指定が必須な理由

どうやら、**「Version specific」（特定バージョン）での用途が前提であるため**のようです。

[Docker Compose の Issue @ GitHub](https://github.com/docker/compose/issues/) にも「バージョン指定がないとイメージをダウンロードできない」現象の報告があがっており、『Docker Compose には `latest` タグはないよ』と、Close されていました。

> There is no `latest` tag uploaded for Docker Compose. 
> （[Issue #6006 のコメント](https://github.com/docker/compose/issues/6006#issuecomment-427413560)より）

しかも、『Manifest に `latest` タグを付けてはくれまいか』という要望（[Issue #6331](https://github.com/docker/compose/pull/6331)）すらも『[以前説明した](https://github.com/docker/compose/issues/5987#issuecomment-392113124)通り、（`latest`タグを付ける）予定なんか、ないよ』とのことで、Docker Compose の中の人に却下されていました。

> Thanks!
> As explained [here](https://github.com/docker/compose/issues/5987#issuecomment-392113124), that's not something we're currently looking to do.
> <sup>（[Issue #6331 のコメント](https://github.com/docker/compose/pull/6331#issuecomment-437126580)より）</sup>

その「[以前の説明](https://github.com/docker/compose/issues/5987#issuecomment-392113124)」とやらを読むと、どうやら「**バージョンを限定しての用途で DockerHub に提供している**」ことが理由のようです。

> If you're talking about the `docker/compose` image on Hub, it's meant to be exclusively used through the `run.sh` script, which is versioned.
> We currently have no plans to add a latest tag.
> <sup>（[Issue #5987 | Compose](https://github.com/docker/compose/issues/5987#issuecomment-392113124) @ GitHub の中の人より）</sup>
>
> （筆者訳）
> Docker Hub の `docker/compose` は `run.sh` などの**起動スクリプトで使うことが大前提**なので、バージョン管理の観点からも、動的な **`latest` タグは導入する予定はありません**。
> 

しびあー。

環境依存を減らすのが Docker のいいところでもあるわけで、「Docker Compose 自体が `latest` によって挙動が変わる可能性」を考えると、「動作確認のとれたバージョンを使え」ということなのでしょう。

それ以外はユーザーが疲労コンパイルのもやぶさかではない、と。

### `docker/compose` イメージの最新バージョン・タグ @ DockerHub

これらの Issue から、バージョン指定が必須の理屈もわかりました。しかし、「最新のバージョンを確認したい」というシンプルな要望があります。

手動で確認するなら、リリース・タグの一覧から最新を選べばわかります。

- [Docker Compose のリリース・タグ一覧](https://hub.docker.com/r/docker/compose/tags/) @ DockerHub

しかし、面倒くさい。CircleCI などで最新版で動作テストしたい場合などにも困ってしまいます。そこで API を使って調べることにしましたとさ。

> 🐒 2020/04/04 追記: `docker-compose` v1.25.0 から `latest` タグが使えるようになりました。よかったです。

## 参考文献

- 「[docker get list of tags in repository](https://fordodone.com/2015/10/02/docker-get-list-of-tags-in-repository/)」@ ForDoDone
- 「[How to list all tags for a Docker image on a remote registry?](https://stackoverflow.com/questions/28320134/how-to-list-all-tags-for-a-docker-image-on-a-remote-registry)」@ StackOverflow