Docker初心者のUbuntuコンテナ docker pushとdocker pull(Mac)

スポンサーリンク
クジライメージ Docker
この記事は約20分で読めます。

こんにちは!ともわん(@TomoOne4)です。

僕は、IT企業でマーケティングやセールスをやっています。

Dockerについての第3回目投稿です。

今回は、「Docker HubからpullしてきたUbuntuのコンテナを更新し、それを自分のDocker Hubリポジトリにアップ(push)して、みんなが使えるようにしたら、試しに自分で持ってくる(pull)してみるところまでを扱います。

UbuntuはLunuxのOSですのでこの上でWordPressなども動かす事ができますよ。

今回のポイント

  1. docker pullでDocker Hubからコンテナを構築
  2. 構築したコンテナを更新
  3. 更新したコンテナをdocker pushでDocker Hubの自分のリポジトリに上げる
  4. 上げたリポジトリから、docker pullでDocker Hubからコンテナを構築

ここで書く内容は、Udemy で受講できる、
かめ れおんさんの米国AI開発者がゼロから教えるDocker講座

で学んだ内容を自分の中で定着するために調べたり考えたりした内容を踏まえて進めていきます。

導入は文章より動画のほうがすっと入ってくる人も多いと思いますので、少し記事を読んでいただき

「Docker面白そうだし、簡単そう」

と思った人はぜひUdemyで米国AI開発者がゼロから教えるDocker講座を受けてみてください。

Dockerやコンテナ、仮想化については第1回、第2回がありますのでこちらをみてみてください!

スポンサーリンク

Ubuntuのコンテナ更新

実際の業務では、

Docker Hubから持ってきた(pullしてきた)Docker Imageを

自分(Host)側で必要なライブラリなどを入れて更新して自分たちが使えるようにしていくという流れを取ります。

第2回をご覧いただいた方ならわかるのですが、イメージレイヤーを追加することです。

その方法としては、次の2つがあります。

【実際の業務でのコンテナ更新方法】
1.コンテナからDocker Imageを更新する方法
2.Docker Fileから更新する方法(こっちのほうが一般的)

Docker Fileから更新する方法は別の記事で扱いますので、今回は、コンテナからDocker Imageを更新する方法を取り上げてみます。

コンテナ(Ubuntu)に入り、ディレクトリを1つ追加(更新)してみる

まずは、ubuntuのコンテナにbashで実行します。

$ docker run -it ubuntu bash

root@9bae5479ddfc:/#

現状のコンテナUbuntuのルートディレクトリ直下を確認してみます。

root@9bae5479ddfc:/# ls -l
total 48
lrwxrwxrwx   1 root root    7 Jul  3 01:56 bin -> usr/bin
drwxr-xr-x   2 root root 4096 Apr 15 11:09 boot
drwxr-xr-x   5 root root  360 Aug 11 23:47 dev
drwxr-xr-x   1 root root 4096 Aug 11 23:47 etc
drwxr-xr-x   2 root root 4096 Apr 15 11:09 home
lrwxrwxrwx   1 root root    7 Jul  3 01:56 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Jul  3 01:56 lib32 -> usr/lib32
lrwxrwxrwx   1 root root    9 Jul  3 01:56 lib64 -> usr/lib64
lrwxrwxrwx   1 root root   10 Jul  3 01:56 libx32 -> usr/libx32
drwxr-xr-x   2 root root 4096 Jul  3 01:57 media
drwxr-xr-x   2 root root 4096 Jul  3 01:57 mnt
drwxr-xr-x   2 root root 4096 Jul  3 01:57 opt
dr-xr-xr-x 159 root root    0 Aug 11 23:47 proc
drwx------   2 root root 4096 Jul  3 02:00 root
drwxr-xr-x   1 root root 4096 Jul  6 21:56 run
lrwxrwxrwx   1 root root    8 Jul  3 01:56 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Jul  3 01:57 srv
dr-xr-xr-x  12 root root    0 Aug 11 23:47 sys
drwxrwxrwt   2 root root 4096 Jul  3 02:00 tmp
drwxr-xr-x   1 root root 4096 Jul  3 01:57 usr
drwxr-xr-x   1 root root 4096 Jul  3 02:00 var

ここに Linuxのtouch(ファイルを追加する)コマンドで testというファイルを作成します。

これが、今回の更新内容になります。

※実務ではもっと色々変えていきますが、今回はテストなのでファイル1個追加にとどめておきます。

root@9bae5479ddfc:/# touch test

root@9bae5479ddfc:/# ls -l
total 48
lrwxrwxrwx   1 root root    7 Jul  3 01:56 bin -> usr/bin
drwxr-xr-x   2 root root 4096 Apr 15 11:09 boot
drwxr-xr-x   5 root root  360 Aug 11 23:47 dev
drwxr-xr-x   1 root root 4096 Aug 11 23:47 etc
drwxr-xr-x   2 root root 4096 Apr 15 11:09 home
lrwxrwxrwx   1 root root    7 Jul  3 01:56 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Jul  3 01:56 lib32 -> usr/lib32
lrwxrwxrwx   1 root root    9 Jul  3 01:56 lib64 -> usr/lib64
lrwxrwxrwx   1 root root   10 Jul  3 01:56 libx32 -> usr/libx32
drwxr-xr-x   2 root root 4096 Jul  3 01:57 media
drwxr-xr-x   2 root root 4096 Jul  3 01:57 mnt
drwxr-xr-x   2 root root 4096 Jul  3 01:57 opt
dr-xr-xr-x 159 root root    0 Aug 11 23:47 proc
drwx------   2 root root 4096 Jul  3 02:00 root
drwxr-xr-x   1 root root 4096 Jul  6 21:56 run
lrwxrwxrwx   1 root root    8 Jul  3 01:56 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Jul  3 01:57 srv
dr-xr-xr-x  12 root root    0 Aug 11 23:51 sys
-rw-r--r--   1 root root    0 Aug 11 23:51 test
drwxrwxrwt   2 root root 4096 Jul  3 02:00 tmp
drwxr-xr-x   1 root root 4096 Jul  3 01:57 usr
drwxr-xr-x   1 root root 4096 Jul  3 02:00 var

testファイルが追加されました。

更新ができたので、exitで一度コンテナから抜けます。

root@9bae5479ddfc:/# exit

それでは、イメージを確認してみます。

$ docker ps -a

CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS                       PORTS                    NAMES
9bae5479ddfc        ubuntu                 "bash"                   6 minutes ago       Exited (0) 52 seconds ago                             charming_heyrovsky

すると、作ったコンテナがありますが、STATUSがExitedなので、起動していません。(exitでコンテナを抜けたので、当たり前なのですが・・・)

そこで、起動するために、restartします。

docker restart {Container ID / Container Name}

$ docker restart 9bae5479ddfc
9bae5479ddfc

すると docker ps -aコマンドでもう一度プロセスを見てみると、

$ docker ps -a

CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS                      PORTS                    NAMES
9bae5479ddfc        ubuntu                 "bash"                   14 hours ago        Up About a minute                                    charming_heyrovsky

STATUSが Up になっているのがわかります。

そこからDocker ContainerのUbuntuの中に入る(bash)場合には、docker execを使います。

docker exec -it <Container Name> bash

すでにコンテナはUpしているので、そのコンテナを指定してEXEC(実行)させるということです。

実行させるプログラムは、その後に指定します。(今回は、bash)

$ docker exec -it 9bae5479ddfc bash

root@9bae5479ddfc:/#

コンテナのUbuntuに入れました。

ちなみに、

Dockerが動いていない状態(Exited)でdocker execコマンドを実行すると、エラーが出ます。

Error response from daemon: Container 9bae5479ddfcd537a8a62125679fc1acecbfbeafb639842b22569e3928bf3e11 is not running

これは、あまり使わない方法ですが、デタッチという方法でコンテナから出ると、プロセスは維持したままコンテナから出られます。

デタッチは、 ctrl + q + p

です。

デタッチしたあとに再度コンテナに入るには、アタッチを行います。

docker attach <Container ID>

$ docker attach 9bae5479ddfc

root@9bae5479ddfc:/#

【exitとデタッチの違い】
exitは、コンテナを抜けるときにプロセスを切ってから抜けるため、Exitedステータスになる。再度コンテナへ入るときには docker restartコマンドを実行する。

デタッチは、コンテナを抜けるときにプロセスを維持したまま抜けるため、Upステータスのままになる。再度コンテナへ入るときにはdocker attachコマンドを実行する。

コンテナをCommitして、Docker Image化

次は、更新したコンテナをcommitしていきます。Gitと同じ感じです。

ドキュメントでは、こう書いてあります。

コンテナのファイル変更や設定を、新しいイメージに収容(commit;コミット)するために便利です。これにより、インタラクティブなシェル上でコンテナをデバッグ用に動かしたり、作業中のデータセットを他のサーバに持っていくため出力したりできます。通常は、イメージを管理するためには、文書化されメンテナンスのしやすい Dockerfile を使うのが望ましい方法です。 詳細はイメージ名とタグについてをご覧ください 。

commit

コマンドはこちらです。

docker commit <Container ID> <New Image Name>

$ docker commit 9bae5479ddfc ubuntu:updated

sha256:4a2d7b4af3079f138657310ada4a6c821af5cccf28dc5cb201f61e7a8fd58249

最後のubuntu:updatedの部分は、リポジトリ名:タグ名を指定しています。

コミットしたら、 docker imagesコマンドでイメージを見てみます。すると、

$ docker images

REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZ
ubuntu                         updated             4a2d7b4af307        38 seconds ago      73.9MB

無事にcommitできているようです!

Docker Hubリポジトリを作成し、別名でDocker Imageを登録、push

Docker Hubのリポジトリは、Docker Hubのサイトに行くといろんなイメージが登録されているのですが その入れ物のことをいいます。

Docker Hubを見るとわかるのですが、基本的にリポジトリはイメージ単位に用意するものとなります。

厳密には、

Repository name:Tag name

となり、このなかのRepository nameの部分をImage nameと呼ぶこともあれば、Tag nameまでを含めてImage nameと呼ぶこともあるようです。

Ubuntuの場合ですと、
library/ubuntu:latest
のこれが、ubuntu の Image nameとなります。

※Tag nameの指定をしないと自動でlatestが入ります。

ここが重要なのですが、

イメージ名とリポジトリ名は同じでなければならないということです!

Docker Hubにリポジトリを作成

Docker Hubにリポジトリを作っていきます。

アカウントを取得している前提でDocker Hubに入ります。

Create a Repositoryをクリックし、リポジトリの名前をつけてCreateするだけで完了です!

今回は、my-first-repoとしています。

作成したDocker Imageをpush

イメージの名前を見て、pushをしていきます。

docker tag <source> <target>

docker tag ubuntu:updated <username>/my-first-repo

詳細に言うと、こうなります。↓

<hostname>:<port>/<username>/<repository>:<tag>

【解説】
<hostname>:<port>・・・Docker Hubの場合は省略できる(デフォルトで は、Docker Hubのregistry1-docker.io)
<username>・・・デフォルトでは、library
<tag>・・・デフォルトでは、latest

Docker Hub以外にpushする時は、正式な指定が必要です。

実際にやってみます。(usernameはxxxxxxxxにしております。)

$ docker tag ubuntu:updated xxxxxxxxx/my-first-repo

$ docker images

REPOSITORY                            TAG                 IMAGE ID            CREATED             SIZE
ubuntu                                updated             4a2d7b4af307        11 hours ago        73.9MB
xxxxxxxx/my-first-repo                latest              4a2d7b4af307        11 hours ago        73.9MB

同じIMAGE IDで違うレポジトリ名で指定したタグ名のものができているのがわかります。

→ 同じイメージに対して複数のタグが付いているイメージです。

それでは、pushしていきます。

docker push <image name>

$ docker push xxxxxxxx/my-first-repo

The push refers to repository [docker.io/xxxxxxxx/my-first-repo]
d5bd72a8e6b0: Pushed
544a70a875fc: Layer already exists
cf0f3facc4a3: Layer already exists
132bcd1e0eb5: Layer already exists
d22cfd6a8b16: Layer already exists
latest: digest: sha256:6fafbe226353cdc354c293d8cc1e8ccb4d8c8bbdb30c3be0bc562c2548bc0540 size: 1359

すると、5つのDocker Imageレイヤーが用意されていて、そのうちの一番上がpushされているのが見えます。

それ以外のイメージレイヤーはubuntuイメージのレイヤーから利用しているので効率的という話は前回の記事でしました。

Docker Hubに行くと、pushしたことがわかります。

作成したDocker Imageをpull

これで、Docker Hubには上がったのでそこからpullしてみます。

(自分であげたDocker Imageを自分でpullしてくる感じになっていますが、本来は開発しているチームのみんながpullしてくれる想定です。)

そのためには、一度pullするイメージを消してから、pullします。

$ docker images

REPOSITORY                            TAG                 IMAGE ID            CREATED             SIZE
xxxxxxxx/my-first-repo                latest              4a2d7b4af307        11 hours ago        73.9MB

今回は、xxxxxxxx/my-first-repo をpullしてくることをやって見るので、同じ名前のイメージをpullできないため、一度消すという作業を行います。

【イメージの削除】
docker rmi <image name>

$ docker rmi xxxxxxxx/my-first-repo

Untagged: xxxxxxxx/my-first-repo:latest
Untagged: xxxxxxxx/my-first-repo@sha256:6fafbe226353cdc354c293d8cc1e8ccb4d8c8bbdb30c3be0bc562c2548bc0540

消えました!

それではpullしていきます。

コマンドは、Docker HubのTagsの右上にあるコマンドをコピーして貼り付けて実行です。

$ docker pull xxxxxxxx/my-first-repo:latest

latest: Pulling from xxxxxxxx/my-first-repo
Digest: sha256:6fafbe226353cdc354c293d8cc1e8ccb4d8c8bbdb30c3be0bc562c2548bc0540
Status: Downloaded newer image for xxxxxxxx/my-first-repo:latest
docker.io/xxxxxxxx/my-first-repo:latest

それでは、確認していきます。

$docker images

REPOSITORY                            TAG                 IMAGE ID            CREATED             SIZE
xxxxxxxx/my-first-repo                latest              4a2d7b4af307        11 hours ago        73.9MB

無事に、pullできていることを確認できました。

docker runしてpullしてきたコンテナに入ってみます。

$ docker run -it xxxxxxxx/my-first-repo bash

root@63463f42d2ed:/# ls -l
total 52
lrwxrwxrwx   1 root root    7 Jul  3 01:56 bin -> usr/bin
drwxr-xr-x   2 root root 4096 Apr 15 11:09 boot
drwxr-xr-x   5 root root  360 Aug 13 01:32 dev
drwxr-xr-x   1 root root 4096 Aug 13 01:32 etc
drwxr-xr-x   2 root root 4096 Apr 15 11:09 home
lrwxrwxrwx   1 root root    7 Jul  3 01:56 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Jul  3 01:56 lib32 -> usr/lib32
lrwxrwxrwx   1 root root    9 Jul  3 01:56 lib64 -> usr/lib64
lrwxrwxrwx   1 root root   10 Jul  3 01:56 libx32 -> usr/libx32
drwxr-xr-x   2 root root 4096 Jul  3 01:57 media
drwxr-xr-x   2 root root 4096 Jul  3 01:57 mnt
drwxr-xr-x   2 root root 4096 Jul  3 01:57 opt
dr-xr-xr-x 161 root root    0 Aug 13 01:32 proc
drwx------   1 root root 4096 Aug 11 23:52 root
drwxr-xr-x   1 root root 4096 Jul  6 21:56 run
lrwxrwxrwx   1 root root    8 Jul  3 01:56 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Jul  3 01:57 srv
dr-xr-xr-x  12 root root    0 Aug 11 23:51 sys
-rw-r--r--   1 root root    0 Aug 11 23:51 test
drwxrwxrwt   2 root root 4096 Jul  3 02:00 tmp
drwxr-xr-x   1 root root 4096 Jul  3 01:57 usr
drwxr-xr-x   1 root root 4096 Jul  3 02:00 var

testファイルもありますね。

これで、自分が作ったDocker ImageをDocer Hubにpushして、だれでもpullしてこれることを確認できました!(^^)

まとめ

長くなってしまいましたが、この流れを踏めばpullしてコンテナ更新してpushしてみんなに使ってもらえるという業務に近い流れが分かったかと思います。

ここまでできるとDockerって面白くなってきますね!

教材と参考資料

米国AI開発者がゼロから教えるDocker講座
AI開発のプロが徹底的に現場目線でわかりやすく教えます.Dockerを使って超本格的なデータサイエンスやWeb開発の環境が作れるようになります.
Artifactory - ユニバーサルアーティファクト管理
世界初のユニバーサルリポジトリとして、JFrog ArtifactoryはJFrog Platformのミッションクリティカルな中心部であり、DevOpsパイプライン全体を移動するすべてのパッケージの信頼できる単一のソースとして機能します。

タイトルとURLをコピーしました