跳至主要内容

4.8 本地建立映像檔儲存庫

雖然後面的章節會教學如何把映像檔儲存庫部署到網際網路上,但還是要先在本地端嘗試一下映像檔儲存庫的容器執行起來是什麼樣子,以及如何在沒有畫面的情況下和映像檔儲存庫做互動呢?

輸入下方指令:

$ docker run -d -p 5000:5000 --name registry --env REGISTRY_STORAGE_DELETE_ENABLED=true registry:2 # 不換行
53efa11dfca5342c348f71e417302969180c4db5a046cca....

這時候本地端就已經運行了一個映像檔儲存庫了,讓我們試著把剛才重新貼標籤的映像檔再換一個新的標籤吧。

$ docker image tag robeeerto/nginx:latest localhost:5000/robeeerto/nginx:latest # 不換行

接著把它推進去本地運行起來的映像檔儲存庫內:

$ docker image push localhost:5000/robeeerto/nginx:latest
The push refers to repository [localhost:5000/robeeerto/nginx]
b539cf60d7bb: Pushed
bdc7a32279cc: Pushed
f91d0987b144: Pushed
3a89c8160a43: Pushed
e3257a399753: Pushed
92a4e8a3140f: Pushed
latest: digest: sha256:f26fbadb0acab4a21e25669d99ed1261 size: 1570

但因為本地的映像檔儲存庫不像 DockerHub 有漂亮的使用者介面來讓我們清楚的看到自己推上去的映像檔,所以需要透過官方提供的 API 來確認是否有正確的將映像檔送進去。

一樣可以透過 curl 這個工具做確認:

$ curl http://localhost:5000/v2/robeeerto/nginx/tags/list
{"name":"robeeerto/nginx","tags":["latest"]}

可以看到推送進去的 robeeerto/nginx:latest 確實已經存在本地的映像檔儲存庫之中,接著試著使用官方提供的 API 來刪除掉儲存庫內的映像檔,但發現刪除映像檔還需要映像檔本身的 digest。

刪除映像檔的 API

這時候需要找到另一個可以得到 digest 的 API 才能刪除掉這個映像檔,透過閱讀官方的文件可以得知下方這個 API 能夠得到映像檔的 manifest。

取得映像檔的 manifest

仔細閱讀發現可以透過 HEAD 的方式取得這個映像檔的 digest 值,繼續使用 curl 這個工具來取得資料。

$ curl --head http://localhost:5000/v2/robeeerto/nginx/manifests/latest -H 'Accept: application/vnd.docker.distribution.manifest.v2+json'
# 不換行

HTTP/1.1 200 OK
Content-Length: 1570
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Docker-Content-Digest: sha256:f26fbadb0acab4a21ecb4e337a326907e61fbec36c9a9b52e725669d99ed1261
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:f26fbadb0acab4a21ecb4e337a326907e61fbec36c9a9b52e725669d99ed1261"
X-Content-Type-Options: nosniff
Date: Sun, 04 Sep 2022 10:26:59 GMT

最重要的資訊就是這行:

Docker-Content-Digest: sha256:f26fbadb0acab4a21ecb4e337a326907e61fbec36c9a9b52e725669d99ed1261

接著拿著得到的 digest 去請求刪除的 API。

$ curl -X DELETE http://localhost:5000/v2/robeeerto/nginx/manifests/sha256:f26fbadb0acab4a21ecb4e337a326907e61fbec36c9a9b52e725669d99ed1261 # 不換行
# 沒有反應是正常的

再次透過 API 來確認目前映像檔儲存庫內的映像檔:

$ curl http://localhost:5000/v2/robeeerto/nginx/tags/list
{"name":"robeeerto/nginx","tags":null}

可以看到原本擁有 latest 的標籤現在變成了 null。

或許這樣子的方式會讓人覺得自己建立映像檔儲存庫很麻煩,但後面在部署的章節,會搭配開源的映像檔儲存庫 UI 介面一起部署,就可以像操作 DockerHub 的方式來管理自己的儲存庫。