Docker超入門④〜コンテナをcommitしてレジストリにアップロードする〜【初心者向け】

グローバルでAI開発者・データサイエンティストを目指す人向け
おすすめUdemy講座一覧

TOEIC300→海外就職の英語勉強法まとめ

こんにちは,米国データサイエンティストのかめ(@usdatascientist)です.

Docker入門も4回目に突入です!今日はコンテナをcommitしてDocker imageとして保存し,それをDocker Hubにアップしてみたいと思います.

前回の記事で,ubuntuのDocker imageをrunしてコンテナを作り,そこにtestというファイルを作ってコンテナから抜けましたね.
(まだ前回の記事を読んでいない方は,↓から読んでくださいね〜)

Docker超入門③〜Dockerコンテナを使ってみる〜【初心者向け】

実業務ではチームの開発者全員が同じ環境を使って開発する必要があります.Dockerをそれを簡単に可能にするためのツールでした.

他にも,CI/CD(テストやデプロイを自動化するパイプラインのこと)で使う環境や,本番環境で使う環境も揃えたりします.
テスト環境が本番の環境と違かったらテストにならないですからね〜

ということは,前回の記事でコンテナを更新したならそれを今度はチームのメンバーに共有する必要があります.

そこで,今回の記事ではコンテナをcommit(saveのようなもの)し新しいDocker imageを作ってDocker Hubにアップロードして他の人がpullできるようにしましょう!

コンテナをcommitしてDocker imageにする

まず,前回のコンテナに入り,ちゃんとtestファイルがあることを確認しましょう.

$docker ps -a  でコンテナの一覧を確認し, $docker exec -it {コンテナ名またはID} bash  でコンテナに入ります.もしSTATUSがExitedになっていたら $docker restart {コンテナ名} でrestartさせてから $docker exec -it {コンテナ名またはID} bash でコンテナに入りましょう.

ちゃんとtestファイルがありますね? では,コンテナから出てcommitします

うさぎ
commitってなんだっけ??

commitというのはコンテナを新しいDocker imageとして保存することです.前回コンテナにtestファイルを追加しましたが,このコンテナを他のメンバーに共有したいですよね?そのために一度Docker imageとして保存して,他のメンバーに配布できる形にします.

commitのコマンドは $ docker commit {コンテナ名またはID} {新しいDocker image} で,コンテナの外で実行します.

今回はdetachしてcommitします.exitでもOKです.

$docker images  で ubuntu:updated が保存されていることを確認します.

ちゃんと新しいimageができてます.(TAG名:updated)

それでは,このimageをrunしてコンテナをもう一度作ってtestファイルがあるちゃんとあることを確認してみましょう!

ちゃんとtestがありますね!

Docker imageをDocker Hubにpushする

新しいDocker imageを作ったら,チームのメンバーに共有したり,配布できるようにしたいですよね? 例えばDocker imageを.tarファイルにして送信することもできますが,Dockerレジストリにアップロードしてそれをメンバーがpullできるようにするのが一般的です.今回はDocker Hubにアップロードしてみます.

Docker imageのアップロードは $git push でできます.Gitと同じですね! まずはDocker Hubに保存先のリポジトリをつくりましょう!今回は「my-first-repo」というリポジトリを作ります.Docker Hubにアクセスし,以下の手順で作ります.

めちゃくちゃ簡単ですね. {Username}/my-first-repo が作られていると思います.

補足
Github同様,リポジトリ名は - (ハイフン)で単語を繋ぐのが一般的です
 

さて,それでは ubuntu:latestmy-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を何回も更新するからね!)

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します.

どうやらpushできたみたいですね.

ここで出力結果をみてみると,1つ目のimage layerのみpushされており,残りの4つはマウント(場所だけ記録してそこにアクセスできるようにする)しているようです.前回の記事で,image間で同じimage layerを共有することでストレージを節約しているといいました.まさにここでも,既にDocker Hubにあるubuntuイメージを共有しているわけです.

ぺんぎん
一つ目のlayerは,自分でtestファイルを追加した分のlayerかな?

その通り,実は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を削除します.
testファイルがあることが確認できます♪もう慣れてきましたか?

第一回〜今回で,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について学んでいこうと思います!では!

追記: 次回の記事書きました.↓

Docker超入門⑤〜Dockerfileを使う〜【初心者向け】