こんにちは,米国データサイエンティストのかめ(@usdatascientist)です.
Docker入門も4回目に突入です!今日はコンテナをcommitしてDocker imageとして保存し,それをDocker Hubにアップしてみたいと思います.
前回の記事で,ubuntuのDocker imageをrunしてコンテナを作り,そこにtestというファイルを作ってコンテナから抜けましたね.
(まだ前回の記事を読んでいない方は,↓から読んでくださいね〜)
実業務ではチームの開発者全員が同じ環境を使って開発する必要があります.Dockerをそれを簡単に可能にするためのツールでした.
他にも,CI/CD(テストやデプロイを自動化するパイプラインのこと)で使う環境や,本番環境で使う環境も揃えたりします.
テスト環境が本番の環境と違かったらテストにならないですからね〜
ということは,前回の記事でコンテナを更新したならそれを今度はチームのメンバーに共有する必要があります.
そこで,今回の記事ではコンテナをcommit(saveのようなもの)し新しいDocker imageを作ってDocker Hubにアップロードして他の人がpullできるようにしましょう!
(追記:Docker動画講座作りました.Dockerについてもっと学びたい人は是非!14時間にも及ぶ超壮大講座です.
目次
コンテナをcommitしてDocker imageにする
まず,前回のコンテナに入り,ちゃんとtestファイルがあることを確認しましょう.
1 2 3 4 5 6 |
~ (🐢) :$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e8d053a58c8a ubuntu "bash" 24 hours ago Up 22 hours dreamy_herschel ~ (🐢):$ docker exec -it dreamy_herschel bash root@e8d053a58c8a:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys test tmp usr var |
$docker ps -a でコンテナの一覧を確認し, $docker exec -it {コンテナ名またはID} bash でコンテナに入ります.もしSTATUSがExitedになっていたら $docker restart {コンテナ名} でrestartさせてから $docker exec -it {コンテナ名またはID} bash でコンテナに入りましょう.
ちゃんとtestファイルがありますね? では,コンテナから出てcommitします
commitというのはコンテナを新しいDocker imageとして保存することです.前回コンテナにtestファイルを追加しましたが,このコンテナを他のメンバーに共有したいですよね?そのために一度Docker imageとして保存して,他のメンバーに配布できる形にします.
commitのコマンドは $ docker commit {コンテナ名またはID} {新しいDocker image名} で,コンテナの外で実行します.
今回はdetachしてcommitします.exitでもOKです.
1 2 3 |
root@e8d053a58c8a:/# read escape sequence ~ (🐢 ) :$ docker commit dreamy_herschel ubuntu:updated sha256:990bb503d3cdf2779f45a7f0070b7a8d30711a445ac5fbdcf110f7daf4ce7855 |
$docker images で ubuntu:updated が保存されていることを確認します.
1 2 3 4 |
~ (🐢) :$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu updated 990bb503d3cd About a minute ago 64.2MB ubuntu latest 549b9b86cb8d 2 weeks ago 64.2MB |
ちゃんと新しいimageができてます.(TAG名:updated)
それでは,このimageをrunしてコンテナをもう一度作ってtestファイルがあるちゃんとあることを確認してみましょう!
1 2 3 |
~ (🐢 ) :$ docker run -it ubuntu:updated bash root@68a634251c09:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys test tmp usr var |
ちゃんとtestがありますね!
Docker imageをDocker Hubにpushする
新しいDocker imageを作ったら,チームのメンバーに共有したり,配布できるようにしたいですよね? 例えばDocker imageを.tarファイルにして送信することもできますが,Dockerレジストリにアップロードしてそれをメンバーがpullできるようにするのが一般的です.今回はDocker Hubにアップロードしてみます.
Docker imageのアップロードは $docker push でできます.Gitと同じですね! まずはDocker Hubに保存先のリポジトリをつくりましょう!今回は「my-first-repo」というリポジトリを作ります.Docker Hubにアクセスし,以下の手順で作ります.
めちゃくちゃ簡単ですね. {Username}/my-first-repo が作られていると思います.
Github同様,リポジトリ名は - (ハイフン)で単語を繋ぐのが一般的です
さて,それでは ubuntu:updated を my-first-repo にpushします.
ここで一点注意が必要なのが, ubuntu というimageはDocker Hub Library にあったubuntuというリポジトリからpullしたものでした.実は,pushするときにDockerは,image名を元にpush先を決めます.そのため,通常リポジトリ名=image名とし,VersionをTAG名で管理します.
つまり今回の場合は,push先が {Username}/my-first-repo なら,image名も {Username}/my-first-repo にし,pushします.そうすることで「もうこのimageはubuntuのリポではなく自分のもの」と区別できます.
違うimage名で保存するには, $ docker tag {旧IMAGE名:旧TAG名} {新IMAGE名:新TAG名} でできます.(実業務ではTAG名を変えることの方が頻出. 実際には同じリポのimageを何回も更新するからね!)
1 2 3 4 5 6 |
~ (🐢 ) :$ docker tag ubuntu:updated datascientistus/my-first-repo:latest ~ (🐢 ) :$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE datascientistus/my-first-repo latest 990bb503d3cd 3 hours ago 64.2MB ubuntu updated 990bb503d3cd 3 hours ago 64.2MB ubuntu latest 549b9b86cb8d 2 weeks ago 64.2MB |
datascientist/my-first-repo という新しいimageができました.
ここで, ubuntu:updated と datascientistus/my-first-repo という二つのimageのIMAGE IDが同じことに気づいたでしょうか?
そしてカラムをみてわかる通り,image名ではなくRepositoryになっていますね.そう,いままでimage名と読んでいたものは実はrepository名とも言え,image名=repository名であることがわかると思います.そして,それらは全く同じimageを指しているのです.(便宜上,image名と呼んでいるだけです.)
それでは, $docker push IMAGE名(レポジトリ名) でいよいよDocker Hubにpushします.
1 2 3 4 5 6 7 8 |
~ (🐢 ) :$ docker push datascientistus/my-first-repo The push refers to repository [docker.io/datascientistus/my-first-repo] e2879e24ff19: Pushed 918efb8f161b: Mounted from library/ubuntu 27dd43ea46a8: Mounted from library/ubuntu 9f3bfcc4a1a8: Mounted from library/ubuntu 2dc9f76fb25b: Mounted from library/ubuntu latest: digest: sha256:3b44cfa5ec2840dea799e7f94e98a1b3907148ba85e9b71f633c681e4b7d19c9 size: 1359 |
どうやらpushできたみたいですね.
ここで出力結果をみてみると,1つ目のimage layerのみpushされており,残りの4つはマウント(場所だけ記録してそこにアクセスできるようにする)しているようです.前回の記事で,image間で同じimage layerを共有することでストレージを節約しているといいました.まさにここでも,既にDocker Hubにあるubuntuイメージを共有しているわけです.
その通り,実はimageをrunしてコンテナを実行すると,新しい「上書き可能なimage layer」(R/W layer)ができ,コンテナでの作業はそこに記録されます.
もしubuntuのimageで複数のコンテナを実行したら,それぞれのコンテナはubuntuの4枚のimage layersを共有し,それぞれのコンテナで新しいR/W layerが作られるイメージです. また,もとのubuntuの4枚のlayerはロックされていて上書きはできません.
Docker Hubでpushされたimageを確認する
それでは,https://hub.docker.com/repository/docker/{username}/my-first-repoにアクセスし,imageがpushされていることを確認してみましょう.
これで,チームのメンバに新しいimageを共有できます.
試しにこのimageをpullして中を確認してみます. すでに同じimageがローカルにあるので,一度imageを消してrunしてみましょう.
$ docker rmi {IMAGE名} でimageを削除します.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
~ (🐢 ) :$ docker rmi datascientistus/my-first-repo Untagged: datascientistus/my-first-repo:latest Untagged: datascientistus/my-first-repo@sha256:3b44cfa5ec2840dea799e7f94e98a1b3907148ba85e9b71f633c681e4b7d19c9 ~ (🐢 ) :$ docker pull datascientistus/my-first-repo:latest latest: Pulling from datascientistus/my-first-repo Digest: sha256:3b44cfa5ec2840dea799e7f94e98a1b3907148ba85e9b71f633c681e4b7d19c9 Status: Downloaded newer image for datascientistus/my-first-repo:latest ~ (🐢 ) :$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE datascientistus/my-first-repo latest 990bb503d3cd 3 hours ago 64.2MB ~ (🐢 ) :$ docker run -it datascientistus/my-first-repo bash root@411decc691ef:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys test tmp usr var |
第一回〜今回で,Docker imageをpullしてrunしてexitしてpushするという一通りの操作を学びました!お疲れ様でした〜
まとめ
今回はコンテナをcommitし,Docker imageを作り,レジストリに作ったリポジトリにpushするというところまでをやりました.
これで一通り,Dockerの基本操作をマスターしたことになります.もうなんとなくDocker imageとコンテナについてわかってきたのではないかと思います.
今回学んだ内容をまとめると↓
- $ docker commit {コンテナ名} {イメージ名} : コンテナをimage化
- docker imageの共有はDockerレジストリ(今回はDocker Hub)にリポを作る.
- リポジトリ名=イメージ名
- $ docker tag {旧IMAGE名:旧TAG名} {新IMAGE名:新TAG名} :新しいイメージ名,タグ名で保存
- $ docker push イメージ名(リポジトリ名) :imageをpush
いやーここまで長かったですが
実はまだまだ続きます.(!?)
まだDockerfileをやってないですよ・・・
今回コンテナを直接更新して新しいimage layerを作りましたよね?でも,これだと新しいimage layerがどんな更新されたかわからないんです.なので実業務では,コンテナを直接更新してimageを更新していくということはあまりしません.
ではどうするのかというと,Dockerfileというテキストファイルに「◯◯をインストールする」とか今回の例でいうと「testというファイルを作成する」といった命令コマンドを書いていくことで可視化するのが一般的です.
てことで,次回はDockerfileについて学んでいこうと思います!では!
追記: 次回の記事書きました.↓