Docker Private Registryのtagとrepositoryを削除する方法

1. ヘッダーにAccept: application/vnd.docker.distribution.manifest.v2+jsonを追加して、Get /v2/<イメージ名>/manifests/<タグ>でマニフェストを取得(https://docs.docker.com/registry/spec/api/#pulling-an-image)

2. レスポンスのヘッダーに付いてくる[Docker-Content-Digest]を確認。

3. Delete /v2/<イメージ名>/manifests/<Docker-Content-Digest>の実行。

4. registryコンテナ本体でbin/registry garbage-collect /path/to/config.ymlを実行してガーベッジコレクションを起動。
https://docs.docker.com/registry/garbage-collection/

4. 対象のrepositoryディレクトリを手動削除。

準備

Amazon Linux release 2 (Karoo)

```
# amazon-linux-extras install -y docker=18.03.1のようにバージョン指定でインストールも可能
$ sudo amazon-linux-extras install -y docker

# dockerサービス起動
$ sudo systemctl start docker

# DockerはUnixソケットをTCPポートにバインドするため、
# rootユーザーでしか動作しません。sudoコマンドを
# 使いたくないという場合は、dockerグループを作成して
# そこにユーザーを追加してください
# なお、sudoコマンドでdockerコマンドを実行できるように
# するには、dockerグループにユーザー追加後にログオフして
# 再度ログインする必要があります
$ sudo usermod -a -G docker $USER

# 確認コマンド
$ cat /etc/group | grep docker

# dockerサービスの自動起動を有効にする
$ sudo systemctl enable docker
```

```
# Docker Private Registryコンテナ起動
$ docker run -d --name testreg \
  -e REGISTRY_STORAGE_DELETE_ENABLED=true \
  -p 5000:5000 registry:2

# Docker Private Registryにalpineのイメージを登録
$ docker pull alpine:latest
$ docker tag alpine:latest 127.0.0.1:5000/myrepo:tag1
$ docker push 127.0.0.1:5000/myrepo:tag1

# 全てのカタログとタグのリスト取得
$ curl http://127.0.0.1:5000/v2/_catalog

{"repositories":["myrepo"]}

# 対象のタグリスト取得
$ curl http://127.0.0.1:5000/v2/myrepo/tags/list

{"name":"myrepo","tags":["tag1"]}

# 対象のタグ削除
$ digest=$(curl -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -sI http://127.0.0.1:5000/v2/myrepo/manifests/tag1 | grep Docker-Content-Digest | tr '\r\n' ' ' | awk '{print $NF}')

$ curl -X DELETE "http://127.0.0.1:5000/v2/myrepo/manifests/$digest"

# 対象のタグ削除確認
$ curl http://127.0.0.1:5000/v2/myrepo/tags/list

{"name":"myrepo","tags":null}

# config.yml作成
$ sudo mkdir /etc/docker/registry 
$ sudo vi /etc/docker/registry/config.yml
```

``` /etc/docker/registry/config.yml
version: 0.1
storage:
  filesystem:
    rootdirectory: /var/lib/registry
```

```
# ガーベッジコレクション実行
# マニフェストによって参照されなくなったファイルシステムからBLOBを削除
$ docker exec -it testreg registry garbage-collect /etc/docker/registry/config.yml

0 blobs marked, 3 blobs and 0 manifests eligible for deletion
blob eligible for deletion: sha256:57334c50959f26ce1ee025d08f136c2292c128f84e7b229d1b0da5dac89e9866
INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/57/57334c50959f26ce1ee025d08f136c2292c128f84e7b229d1b0da5dac89e9866  go.version=go1.11.2 instance.id=8c036012-29fa-42a4-bdd8-e228153fbfba service=registry
blob eligible for deletion: sha256:b7b28af77ffec6054d13378df4fdf02725830086c7444d9c278af25312aa39b9
INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/b7/b7b28af77ffec6054d13378df4fdf02725830086c7444d9c278af25312aa39b9  go.version=go1.11.2 instance.id=8c036012-29fa-42a4-bdd8-e228153fbfba service=registry
blob eligible for deletion: sha256:0503825856099e6adb39c8297af09547f69684b7016b7f3680ed801aa310baaa
INFO[0000] Deleting blob: /docker/registry/v2/blobs/sha256/05/0503825856099e6adb39c8297af09547f69684b7016b7f3680ed801aa310baaa  go.version=go1.11.2 instance.id=8c036012-29fa-42a4-bdd8-e228153fbfba service=registry

# Docker Private Registryのコンテナ再起動
$ docker restart testreg

# repositoriesディレクトリ確認
$ docker exec -it testreg ls /var/lib/registry/docker/registry/v2/repositories

myrepo

# 対象のrepositoriesディレクトリを削除
$ docker exec -it testreg rm -rf /var/lib/registry/docker/registry/v2/repositories/myrepo

# 全てのカタログとタグのリスト取得
$ curl http://127.0.0.1:5000/v2/_catalog

{"repositories":[]}

# 対象のタグリスト取得
$ curl http://127.0.0.1:5000/v2/myrepo/tags/list

{"errors":[{"code":"NAME_UNKNOWN","message":"repository name not known to registry","detail":{"name":"myrepo"}}]}
```