💨

Windows上からDocker/WSLなしでコンテナイメージをダウンロードするスクリプトを書いた

2023/09/22に公開

使い方

PS> Invoke-WebRequest -Uri https://gist.githubusercontent.com/dama-ewep/8173806f2663e4514b0d565732a74618/raw/docker-pull.ps1 -OutFile ./docker-pull.ps1
PS> ./docker-pull.ps1 hello-world:latest@linux/amd64
  • 引数
    image[:tag][@os[/architecture]][#option]
    image名は完全に一致する必要があるのでDockerHub等で検索してください。
    tagのみ部分一致で結果が複数ある場合はリストの表示のみを行います。
PS> ./docker-pull.ps1 hello-world:lat
==== library/hello-world:lat@/# ====

name                tag    os/arch        ex                         digest
----                ---    -------        --                         ------
library/hello-world latest linux/386                                 sha256:004d23c66201b22fce069b7505756f17088de7889c…
library/hello-world latest linux/amd64                               sha256:7e9b6e7ba2842c91cf49f3e214d04a7a496f821435…
library/hello-world latest linux/arm      variant=v5                 sha256:084c3bdd1271adc754e2c5f6ba7046f1a2c099597d…
library/hello-world latest linux/arm      variant=v7                 sha256:a0a386314d69d1514d7aa63d12532b284bf37bba15…
library/hello-world latest linux/arm64    variant=v8                 sha256:efebf0f7aee69450f99deafe11121afa720abed733…
library/hello-world latest linux/mips64le                            sha256:06bca41ba617acf0b3644df05d0d9c2d2f82ccaab6…
library/hello-world latest linux/ppc64le                             sha256:fbe0ff1e7697da39d987a975c737a7d2fa40b6e7f7…
library/hello-world latest linux/riscv64                             sha256:72ba79e34f1baa40cd4d9ecd684b8389d0a1e18cf6…
library/hello-world latest linux/s390x                               sha256:574efe68740d3bee2ef780036aee2e2da5cf7097ac…
library/hello-world latest windows/amd64  os_version=10.0.17763.4851 sha256:75043f8f1db5630340cb611a64f0bb0f5bd49379cb…
library/hello-world latest windows/amd64  os_version=10.0.20348.1970 sha256:efd257c8ea08ac9905e1b6b547c48f09e35d0916dd…

この結果を元に結果が1件のみとなる条件で指定するとイメージのダウンロードを行います。
hello-world:latestの場合、linux/amd64は「hello-world:latest@linux/amd64」で特定できますが、windowsの場合はos_versionが複数あるため指定する必要があります。

.\docker-search.ps1 hello-world:latest@windows/amd64#os_version=10.0.17763.4851

最後にイメージ名を元にしたtarファイルができるのでこれをDocker運用サーバに持って行ってdockerに食べさせてください。

docker load --input library_hello-world.tar

スクリプト

動作確認環境

Windows10/PowerShell 5.1.19041.3031
Windows10/PowerShell 7.3.7
Windows11/PowerShell 5.1.22621.1778
Windows11/PowerShell 7.3.7

未実装

v1のリストを返すイメージが確認できなかったため、動作確認できていません。
移植元でもTODOとなっていたため、恐らく動きません。

動機

インターネットに接続できないスタンドアロン環境でdockerを運用したい。
docker本体は以下のサイトからダウンロードできるが、イメージはDocker Hubで探してDocker Pullしかなさそう。
https://download.docker.com/linux/static/stable/x86_64/

想定環境

スタンドアロンのDocker運用サーバ
インターネットに繋がるWindowsクライアント(tarコマンドを利用しているのでWindwos10 1803以降)

インターネットに繋がるLinuxサーバがあるなら・・・

やり方を調べているうちにdockerイメージをダウンロードできるbashスクリプトを見つけた
https://raw.githubusercontent.com/moby/moby/master/contrib/download-frozen-image-v2.sh
スクリプトを書いたとは言ったもののこれをPowershellに移植しました。

ハマったこと

  • curl
    HTTPヘッダが独特なのでcurlが必須だった。
    PowerShell組み込みのWebリクエストメソッド(Invoke-WebRequestなど)はリクエストヘッダの設定の際に値をHashmapに持っているが、3種類の"Accept"要素を送信する必要があったため組み込みのメソッドが使えなかった
  -H 'Accept: application/vnd.docker.distribution.manifest.v2+json' \
  -H 'Accept: application/vnd.docker.distribution.manifest.list.v2+json' \
  -H 'Accept: application/vnd.docker.distribution.manifest.v1+json' \

curlを使う以外の回避策がなさそうなのでスクリプトの最初にcurlをダウンロードしてくるようにした。結果的には移植が楽になった。

  • 配列の仕様
    Powershell独特の仕様で配列として宣言しても要素が1個だけの場合、引数や戻り値の受け渡しの際に中身の要素そのものとなってしまう。
function getArray{
  $arr = @("aaa");
  return $arr;
}
$array = getAray
Write-Host $array.GetType().FullName

このコードで期待する結果は「System.Object[]」だが、結果は「System.String」になってしまう。(要素が2個以上、もしくは0個の場合は期待した通りに動く)
最後までハマったが、ダミーデータを突っ込んで利用時に削除という逃げ方をとった。

Discussion