Dockerイメージをファイルで共有する
今回はDockerイメージをDocker Hubを利用せずにファイルで共有する方法です。
社内で共通のDockerイメージを共有する場合など、Docker Hubの利用が制限される場合には有効な手段です。
コマンドには、export/importとsave/loadの2種類がありますが、それぞれ挙動が少し異なります。
どのように違うのか確認したところ下記のようになりました。
Dockerコンテナのexport/import
Dockerコンテナのファイルシステムをexport/importしてみました。
作成したコンテナのファイルシステムをtarアーカイブの形式で出力するにはexportコマンドを使用します。
使い方は
$ docker export [OPTIONS] CONTAINER
です。
それでは、実際にexportしてみます。
$ sudo docker export developer-env | gzip -c > developer-env.tgz
export後のサイズは下記のようになりました。
$ ls -l developer-env.tgz
-rw-r--r-- 1 developer developer 76805143 5月 25 11:42 developer-env.tgz
次に、exportしたtarballから内容を読み込むにはimportコマンドを使用します。
使い方は
$ docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
です。
それでは、さきほどexportしたtarballをimportしてみます。
$ sudo docker import developer-env.tgz
また、下記のようにWEBから直接読み込むような使用方法もあるようです。
$ sudo docker import http://example.com/exampleimage.tgz
今回は、下記のようにimportしてみました。
$ sudo docker import developer-env.tgz
イメージを確認します。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> bb234474c57b 52 seconds ago 168MB
REPOSITORYもTAGも未指定だったので、いずれも<none>となっています。
次に実行します。
$ sudo docker run -d -it --name developer-env bb234474c57b
docker: Error response from daemon: No command specified.
See 'docker run --help'.
エラーで怒られてしまいました。
コンテナに関連づけられたボリュームに含まれる内容を出力しないために、実行コマンドを指定する必要があるようです。
$ sudo docker run -d -it --name developer-env bb234474c57b /bin/bash
5ce860cb73ffdf1092e1a1dddb6e6da888fcdb2a24bd253ab46d93f55ec03ad4
実行中のコンテナ内でコマンドを実行します。
$ sudo docker exec -it developer-env bash
root@5ce860cb73ff:/#
実行コマンドを指定した時点で想像はできたのですが、rootでのログインとなりました。
この使い方は自分のニーズではないようです。
Dockerイメージのsave/load
次にDockerイメージをsave/loadしてみました。
作成した複数のイメージをtarアーカイブの形式で出力するにはsaveコマンドを使用します。
使い方は
$ docker save [OPTIONS] IMAGE [IMAGE...]
です。
先ほどと同じイメージをsaveします。
$ sudo docker save debian:bullseye-ja | gzip > developer-env.tgz
save後のサイズは下記のようになりました。
exportに比べると少し大きいようです。
$ ls -l developer-env.tgz
-rw-r--r-- 1 developer developer 77535089 5月 25 13:36 developer-env.tgz
イメージを取り込むにはloadコマンドを使用します。
使い方は
$ docker load [OPTIONS]
です。
$ sudo docker load < developer-env.tgz
78658088978a: Loading layer [==================================================>] 129.1MB/129.1MB
83cf275345d6: Loading layer [==================================================>] 349.7kB/349.7kB
564586e372a3: Loading layer [==================================================>] 23.49MB/23.49MB
83d0a723ac55: Loading layer [==================================================>] 5.12kB/5.12kB
d0442dfa25b3: Loading layer [==================================================>] 22.94MB/22.94MB
3f3ead373257: Loading layer [==================================================>] 11.78kB/11.78kB
27b4b3e5eaef: Loading layer [==================================================>] 1.172MB/1.172MB
c781741667dd: Loading layer [==================================================>] 3.072kB/3.072kB
9102d579176b: Loading layer [==================================================>] 8.192kB/8.192kB
Loaded image: debian:bullseye-ja
作成時のレイヤを再現することがわかります。
イメージを確認すると下記のようになりました。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
debian bullseye-ja 802df363c999 21 hours ago 171MB
次に実行します。
今回は怒られることがありませんでした。
$ sudo docker run -d -it --name developer-env debian:bullseye-ja
66f0ee8dd74243735c5e47ae7af2eee6783188f53c2d80b8f6e1542978b0717c
実行中のコンテナ内でコマンドを実行します。
$ sudo docker exec -it developer-env bash
developer@66f0ee8dd742:~$
どうも、自分の使い方にはsave/loadのほうが良いようです。
コンテナ上の変更の反映
コンテナに対して加えた修正などは、上記のsave/loadでも反映されません。
そこで、コンテナの変更を反映し、新しいイメージを作成するにはcommitコマンドを使用します。
使い方は
$ docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
です。
実際の使用方法としては
$ sudo docker commit ubuntu-16.04-ja ubuntu-16.04-ja:20220529
という風に使用します。
さきほどと同様にcommitしたイメージを保存すれば完了です。
# sudo docker save ubuntu:16.04-ja | gzip > ubuntu-16.04-ja.tgz
これでコンテナに加えた修正を含めたイメージの保存が完了です。