ビルドしたDockerイメージをリリースする前にテストしたい

# 背景

DockerイメージをCIする場合に、リポジトリにリリースする前にテストしたい。

1. Dockefileからビルド
2. ビルドしたイメージをテスト
3. イメージをリポジトリにリリース

しかし、ビルドした場所とテストでコンテナを起動する場所が異なるので、
ビルドしたイメージのexport, importが必要。

docker save, docker loadでできるみたいなので、その動きを確認しておく。

# 実験 

## 使用するファイル

```:Dockerfile
FROM centos
ENV HOGE=hoge
ENTRYPOINT ["env"]
```

```yaml:docker-compose.yml
version: '3'

services:
  hoge:
    build: .
    image: docker.my.repo.com/hoge
```

## ビルド

```bash:コマンド
docker-compose build --no-cache
```

```bash:実行結果
$ docker-compose build --no-cache
Building hoge
Step 1/3 : FROM centos
 ---> d123f4e55e12
Step 2/3 : ENV HOGE hoge
 ---> Running in 1bd142208f8d
 ---> 9ca0d657e2a1
Removing intermediate container 1bd142208f8d
Step 3/3 : ENTRYPOINT env
 ---> Running in 2e120881ca0e
 ---> 2ba3b869c81b
Removing intermediate container 2e120881ca0e
Successfully built 2ba3b869c81b
Successfully tagged docker.my.repo.com/hoge:latest
```

docker-compose.ymlで指定した、image名でタグ付けされたimageができた。

```bash:作成されたイメージ
$ docker images | grep hoge
docker.my.repo.com/hoge                                  latest              2ba3b869c81b        About a minute ago   197MB
```

IMAGE ID: 2ba3b869c81b


## 書き出す

```bash:コマンド
docker save docker.my.repo.com/hoge > hoge.tar 
```

```bash:保存されたファイル
$ ls -lh hoge.tar
-rw-r--r-- 1 **** 1049089 196M 11月 30 10:51 hoge.tar
```

docker imageで見えたサイズと同等のファイルができた。

## 読み込む

一旦消して

```bash
$ docker rmi docker.my.repo.com/hoge
Untagged: docker.my.repo.com/hoge:latest
Deleted: sha256:2ba3b869c81b8581c27eff26ff642dc5465720e6c1a110fced18746972f1dbd6
Deleted: sha256:9ca0d657e2a1030692dd9cc5e52b5472286933a087b79a20e9c407d7d25d97b4

$ docker images | grep docker.my.repo.com/hoge | wc -l
0
```

読み込んでみる

```bash:コマンド
docker load < hoge.tar 
```

```bash:実行結果
Loaded image: docker.my.repo.com/hoge:latest
```

```bash
$ docker images | grep docker.my.repo.com/hoge
docker.my.repo.com/hoge                                  latest              2ba3b869c81b        13 minutes ago      197MB
```

読み込めた。

CREATEDの日時が、ビルドした時刻になっている。
IMAGE ID: 2ba3b869c81b  も一致

imageが存在する状態でloadしてみる

```bash
$ docker load < hoge.tar
Loaded image: docker.my.repo.com/hoge:latest

$ docker images | grep docker.my.repo.com/hoge
docker.my.repo.com/hoge                                  latest              2ba3b869c81b        16 minutes ago      197MB
```

エラーなしでコマンドが実行完了するが、状態としては変わらず。
saveして出来たファイルから、docker image を読み込めることがわかった。

次にビルドし直した、同REPOSITORY、異IMAGE IDのファイルを読み込んでみる

```
$ docker load < hoge_2.tar
The image docker.my.repo.com/hoge:latest already exists, renaming the old one with ID sha256:17869ea988b2f1b7fcf5d7c91a4712066048ae15db454c1cee78ef565fb0e77e to empty string
Loaded image: docker.my.repo.com/hoge:latest
```

動きが変わった。古いのが存在していたからリネームしたとのこと。

```
$ docker images | grep docker.my.repo.com/hoge
docker.my.repo.com/hoge                                  latest              6f954cf79a47        7 minutes ago       197MB

$ docker images | grep 2ba3b869c81b
<none>                                                   <none>              2ba3b869c81b        27 minutes ago      197MB
```

見てみると、後から読み込んだほうに、docker.my.repo.com/hogeの名前がついていて
もとのIMAGE IDのイメージは、<none>になっていた。

すでに同名のイメージが存在していても、後から読み込んだ最新のイメージを使ってテストを実行できそう。

## タグ

タグを明示して試してみる

```bash
$ docker tag docker.my.repo.com/hoge:latest docker.my.repo.com/hoge:1.0.0
$ docker images

REPOSITORY                                               TAG                 IMAGE ID            CREATED             SIZE
docker.my.repo.com/hoge                                  1.0.0               6f954cf79a47        35 minutes ago      197MB
docker.my.repo.com/hoge                                  latest              6f954cf79a47        35 minutes ago      197MB

$ docker save docker.my.repo.com/hoge:1.0.0 > hoge_1.0.0.tar

$ docker rmi docker.my.repo.com/hoge:1.0.0
Untagged: docker.my.repo.com/hoge:1.0.0

$ docker load < hoge_1.0.0.tar
Loaded image: docker.my.repo.com/hoge:1.0.0


$ docker images
REPOSITORY                                               TAG                 IMAGE ID            CREATED             SIZE
docker.my.repo.com/hoge                                  1.0.0               6f954cf79a47        41 minutes ago      197MB
docker.my.repo.com/hoge                                  latest              6f954cf79a47        41 minutes ago      197MB
```

問題なく、タグ付きで読み込めた。
タグを後からつけても、IMAGE IDは同じ。

#まとめ

docker save, loadを用いて、イメージのリリース前にテストを実行できそう。

テストする環境にすでに同名のイメージが存在していても、後勝ちになるので最新のイメージでテストできそうだが、\<none\> がたまっていくので、使用が終わったイメージを消しておいたほうがよさそう。

また、TAG付きで書き出し・読み込みできるが、テストする環境でどのタグがテスト対象か指定させるよりも、latestを参照させるほうが作りが楽、あとTAGづけしても同じIMAGE IDなので、テスト成功後のpushするまえにTAGづけするのが良さそう。