はじめに
こんにちは。孔子の80代目子孫兼技術5課の孔です。最近暑いなと思っていたら、昨日から雨が降っていて今日は朝からとても寒いですね。おかげさまで途中で起きることなくぐったり寝ることができました。
前回はDockerとは、イメージとは、そしてレイヤーとはどのようなものなのかをみてみました。こちらの知識はDockerの最も基本的な概念となりますが、Dockerを使うにあたってまだまだ必要な基礎知識があります。それが今回ご説明いたします、リポジトリとDockerfile、そしてビルドとなります。それでは、早速みていきましょう。Let's get it!
リポジトリとは
前回の記事でコンテナのベースとなるイメージというものがどのようなものなのか説明しました。このイメージをどのように管理するのかを今からみていきます。前回の記事でhttpdをダウンロードしたこと、覚えてますでしょうか。こちらのものになります。
kong@KongnoAir ~ % docker container run -d httpd Unable to find image 'httpd:latest' locally latest: Pulling from library/httpd afb6ec6fdc1c: Pull complete 5a6b409207a3: Pull complete 41e5e22239e2: Pull complete 9829f70a6a6b: Pull complete 3cd774fea202: Pull complete Digest: sha256:db9c3bca36edb5d961d70f83b13e65e552641e00a7eb80bf435cbe9912afcb1f Status: Downloaded newer image for httpd:latest e29f06721a6e7593240fd73a62a429bb3dde7e63c27bb81679c6196ac5c53f99
コンテナを起動するコマンドを入力したときに、その結果をみてください。まず2行目で”Unable to find image 'httpd:latest' locally”と言われてますね。Dockerはイメージをローカルに保存し、コンテナを起動する際にイメージがローカルにあるかどうかをまずチェックします。もしなかったらイメージをリポジトリにダウンロードしにいきます。それでは、このリポジトリというものは一体何でしょう?
リポジトリはイメージを保管しているサーバとなります。デフォルトではDockerhubが指定されています。Dockerhubに入り、httpdイメージを検索してみるとhttpdというイメージが一番上に出てくるのがわかります。コンテナを起動する際に指定したイメージがローカルになかった場合、リポジトリをみに行ってhttpdがあるかどうかを検索し、あったらダウンロードしてコンテナを起動する流れとなります。
前回使用した図となりますが、こちらのレジストリの中にhubというものがありますね。いろいろなレジストリ上にイメージを保存し、そこからイメージをダウンロードしてコンテナを立ち上げるのが基本的なコンテナ構築の流れです。
デフォルトリポジトリ(Dockerhub)以外のリポジトリを指定するときにはイメージ名の前にurlを指定するだけです。AWSのECRのドキュメントに記載されているコマンドを持ってきました。このように、amazonlinux:latestというイメージをダウンロードする際にaws_account_id.dkr.ecr.us-west-2.amazonaws.com/というurlから持ってきて!という命令になります。(原本はコマンドがdocker pullになっていますが、こちらは任意でdocker image pullに変更しました。コマンドについては次回詳細に説明します)
docker image pull aws_account_id.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:latest
リポジトリを簡単に要約しますと、イメージを蓄えておいて必要なときにダウンロードできる場所、と覚えると良いかと思います。
Dockerfileとは
イメージをリポジトリからダウンロードできることがわかった今、それではこのイメージってどうやって作るんだろうという疑問がそろそろ出てくるのではないかと思います。そのイメージを作成するために必要なものがDockerfileとなります。Dockerfileはイメージをビルドするときに、このイメージがどのようなものなのかを定義したものとなります。以下の例をみてください。
FROM debian:buster-slim ENV NGINX_VERSION 1.17.10 ENV NJS_VERSION 0.3.9 ENV PKG_RELEASE 1~buster <中略> RUN ln -sf /dev/stdout /var/log/nginx/access.log \ && ln -sf /dev/stderr /var/log/nginx/error.log EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
こちらはnginxのDockerfileの一部となります。解説すると
- FROM:ベースイメージとしてどのOSイメージを使用するか(Debianを使用する)
- ENV:環境変数を指定する
- RUN:イメージをビルドする際に実行するコマンドを指定する
- EXPOSE:どのポートを開けるか
- CMD:コンテナを作成する際に実行するコマンドを指定する
となります。もっといろいろなDockerfileのコマンドを知りたい方はこちらのドキュメントをご覧ください。このように、Dockerfileではこのイメージがどのようなイメージとなるのか、その詳細を記入しているファイルだな、ということをイメージできればいいかと思います。
ビルド
Dockerfileを作成したら、ビルドをすることでイメージを作ることができます。以下のシェルをみてください。
kong@KongnoAir ~ % docker image build -t test:latest . Sending build context to Docker daemon 6.499MB Step 1/2 : FROM ubuntu ---> 1d622ef86b13 Step 2/2 : RUN apt-get update ---> Running in 29924a2ea92e Get:1 http://security.ubuntu.com/ubuntu focal-security InRelease [107 kB] <中略> Fetched 13.8 MB in 8s (1659 kB/s) Reading package lists... Removing intermediate container 29924a2ea92e ---> 98d48c9e8359 Successfully built 98d48c9e8359 Successfully tagged test:latest
docker image buildは、Dockerfileをビルドするためのコマンドです。-t オプションはイメージの名前をつけるもので、今回はtestというイメージ名とlatestというタグを付けました。最後の点(.)は「現在のディレクトリにあるDockerfileという名前のファイル」を指定しています。こちらはもちろんパスやファイル名を指定することも可能です。
ビルドの内容をみてみると、ベースのubuntuイメージにapt-get upudateをしているだけのイメージとなります。Dockerfileのそれぞれの命令を見て、イメージを作っていきます。
追加で、こちらのシェル画面もみてください。
kong@KongnoAir code_local % docker image build -t test:latest . ~/Documents/code_local Sending build context to Docker daemon 6.499MB Step 1/2 : FROM ubuntu ---> 1d622ef86b13 Step 2/2 : RUN apt-get update ---> Using cache ---> 98d48c9e8359 Successfully built 98d48c9e8359 Successfully tagged test:latest kong@KongnoAir code_local % docker image build -t test2:latest . Sending build context to Docker daemon 6.499MB Step 1/2 : FROM ubuntu ---> 1d622ef86b13 Step 2/2 : RUN apt-get update ---> Using cache ---> 98d48c9e8359 Successfully built 98d48c9e8359 Successfully tagged test2:latest kong@KongnoAir code_local % docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE test2 latest 98d48c9e8359 2 minutes ago 95.5MB test latest 98d48c9e8359 2 minutes ago 95.5MB httpd latest d4e60c8eb27a 4 days ago 166MB ubuntu latest 1d622ef86b13 3 weeks ago 73.9MB
もう一度同じ名前でビルドをしてみると、今回はStep2のところで”Using cache”と言われています。これが前回説明したレイヤーとなるものです。ビルドしたイメージはレイヤーの重なりであることを覚えていますでしょうか。一回ビルドを行っていたので、レイヤーをDockerデーモンが保持している状態となります。ですので次回もし同じレイヤーを使用するようなビルドがあったらレイヤーを共有してビルドを速度をあげています。イメージ名をtest2に変えた時も同様で、このようにレイヤーを共有することによってDockerはビルドの速度をあげることができています。
最後に
今回はリポジトリ、Dockerfile、そしてDockerfileのビルドまでみてみました。基本的な概念はこれで一通り触れることができたと思いますので、次回は重要なコマンドを一つずつ紹介し、今まで説明した内容をコマンドを使って実際やってみようと思っています。それではお楽しみに!