Docker超入門~通常レベルまで Part2
本記事の内容について
1. Part1の復習
コマンドの復習
dockerイメージをプルする
docker image pull イメージ名
dockerイメージをrunするコマンド
docker container run オプション イメージ名
part1では、dockerについての説明と、なぜ注目されているのか。dockerの仕組みについて説明しました。また、dockerイメージについて軽く説明しました。
本記事では、dockerのコマンドやimageについてもう少し深ぼって説明していきます。
2. dockerイメージ part2
dockerイメージについてコマンドを使いながら説明していきます。
2.1. イメージリストを表示させる
まずは、以下のコマンドを実行してみてください。
docker image ls
画像のように実行結果が表示されると思います。これは、あなたのパソコンのdockerに保存されているdockerイメージです。前回使ったものが入っていると思います。
オプションについて
[-all, -a]
すべてのイメージを表示する
[–digests]
ダイジェスト値を表示する
このコマンドを入れることで、ダイジェスト値を見ることができます。
ダイジェスト値に関しては、こちらを参考にしてみてください。
[-filter, -f]
指定した条件でフィルタ検索を実行する
[–help]
ヘルプコマンドと言って、指定しているコマンドの使い方についてを表示します。
たとえば、–formatを使ってみましょう。
docker image ls --format table
または、
docker image ls --format json
以下のように、dockerイメージの情報を指定したフォーマットで出力してくれます。
dockerに限らず、世の中のコマンドはhelpを用意しているので、ぜひ使ってみてください。
2.2. イメージを削除する
次に、イメージの削除をしてみましょう。
削除コマンドは、以下のとおりです。
docker image rm {IMAGE ID}
削除したいイメージIMAGE IDを指定すると消去することができます。
docker image rm dfbcc2701b93
このようにして削除することができます。
また、削除できない場合は、-fオプションを用いて、強制的に消去することもできます。
docker image rm -f {IMAGE ID}
[–help]
ヘルプコマンドを実行してみましょう。
docker image rm --help
出てきましたね。コマンド覚えていないなーと思った時は、まずドキュメントを検索する前に–helpをすることで時短になることもあるのでぜひ。
3. dockerコンテナ
さて、dockerがなぜ注目されているのか、dockerコンテナ。注目はコンテナであり、dockerのアイコンもコンテナが描かれています。part1では説明しませんでしたが、ホストOS型やハイパーバイザー型の方法と比べてこのdockerがすごいところは、組み換えが可能な点です。
dockerで作る開発環境は、コンテナで管理されています。コンテナを積んでは、消して。消しては積んで。そうやって環境を作っていきます。このコンテナの中にubuntuの環境、nodejsの環境、mysql、pstgresqlの環境など。コンテナごとで管理されます。
図で説明しましょう。たとえば、3つのコンテナ。3つの環境があったとしましょう。
開発途中で、やっぱりこの機能いらないから、環境を消すか。と言って該当する環境を簡単に消去できます。
また、別の環境が必要になった時、簡単に環境を導入することができます。
この、簡単に!!と言うのが結構重要なのです。
ホストOS型やハイパーバイザー型はアプリケーションごとに環境が成り立っているため、データベース周りの環境変えたいな。ちょっとバージョン変更したいな。ということがあった際に、アプリケーション全体のつながりを考えながら慎重に環境を整えて、チームメンバーへの共有、さらには本番環境の構築し直し。dockerに比べるとかなり大袈裟な作業になってしまいます。
3.1. ヘルプコマンドでcontainerが使えるコマンドリストを表示しよう
docker container --help
出力結果
Usage: docker container COMMAND
Manage containers
Commands:
attach Attach local standard input, output, and error streams to a running container
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
exec Execute a command in a running container
export Export a container's filesystem as a tar archive
inspect Display detailed information on one or more containers
kill Kill one or more running containers
logs Fetch the logs of a container
ls List containers
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
prune Remove all stopped containers
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
run Create and run a new container from an image
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
wait Block until one or more containers stop, then print their exit codes
Run 'docker container COMMAND --help' for more information on a command.
主に使いそうなコマンドだけ説明しますと、
run
これは、dockerイメージからコンテナを作成し、さらにコンテナを起動するときに使います。
start
コンテナを起動させるときに使います
stop
コンテナを停止させるときに使います
exec
実行中のコンテナ内でコマンドを実行することができます
rm
コンテナを削除することができます。
他のコマンドは自力で覚えてください。
3.2. おまけ
最近、筆者が勉強しているkubernetesで面白いなと思った技術がありそれに関係しそうなコマンドを教えます。それは、killです。
kubernetesには、グレースフルシャットダウンという仕組みがあり、これは立ち上がっているアプリケーションが予期せぬ事態で強制的にシャットダウンさせられた時、処理中のものでも問答無用で処理が止まってしまうことを防ぐための、その対策としてある仕組みです。なので、killコマンドは、コンテナを強制的に停止させるコマンドなので、関連します。
興味のある方は調べてみてください。
4. dockerボリューム
ボリュームの説明は簡単です。
まず、自分のパソコンで操作しているフォルダやファイルは、dockerで立ち上げたコンテナの中のファイルとは全く別物であるという認識が大事です。
では、環境を作った後どうやるのか。それは、コピーして使います。dockerの中にコピーします。
しかし、毎度毎度コピーすると、たとえば、とても重たいファイルなどがあったときに膨大なコピー時間を要するので大変です。
そこで、ボリュームという考えがあるのです。簡単にいうと、ボリュームというのは記憶領域のことです。コンテナとは別世界に存在します。
その前に、マウントという概念を知っておく必要があります。USBをパソコンに刺す感覚に似ています。全く異なるものではあるのですが、外部から、データを持ってきたときに、どのようにそのデータを読み込むのか。マウントというのは、読み込み方の一つで、パソコンにもともとあるフォルダやファイルに対して、以下の画像の赤い箇所のようにデータを紐づけている。これをマウントという。
では、ボリューム、バインドするとはいったいどういうことか。一言で言うとデータの共有です。
dockerには、3種類のマウント方法があります。ドキュメント
- bind mount
- volume
- tmps mount
tmps mountは、なんとなくわかります。一時的にマウントするデータのこと。
bind mountとvolumeの違いはなんなのでしょうか
それは、管理するところがどこであるのかと言う違いです。
bind mountは、ホストOS側で管理しています。つまり、我々が普段触っているパソコン上のデータです。
volumeは、Dockerが管理しています。(厳密に言えば、dockerそのものもパソコン上のデータとして管理されているので、どちらもパソコン内に存在はしています。ここではあえて、二つを区別するためにそう言う違いとして扱います。)
図で示すと以下のようになります。
Volumesはコンテナで生成されたデータを永続的に保持するために使用しますbind mountはホストマシンのディレクトリ構造に依存しますがvolumesはDockerが管理します
https://blog.shinonome.io/docker-container-mount/
そのため、バックアップや移行がしやすかったり複数コンテナ間で安全に共有できたりします
また、Docker Desktop上のボリュームはMacやWindowsからのbind mountに比べて性能が高いです
4.1. 使いわけ
bind mount
bindmountは、プロジェクトコードをコンテナ内にマウントするときに使用します。
phpで開発します。それをコンテナの中にいちいちコピーして実行するのはめんどくさい。そんなときにbind mountを使用します。自分のパソコンで作業している内容がそのまま反映されるので便利です。
volume
volumeは、データベース関連の情報を保存するときに使います。データベース情報は自分のパソコン内で管理しなくてもよく、他人にも共有したいので、dockerに持たせておくのが良いでしょう。
長く説明しましたが、volumeの使用については、次の記事part3で書きます。
5. Dockerfile
dockerイメージを知っているのなら、簡単です。
Dockerfileとは、自身のパソコンで、dockerイメージを作成するために必要な設計書のことです。
たとえば、PHPの環境が備わったDockerコンテナを作りたい。となったとき、以下のように書きます。
FROM php:7.4-apache
COPY /test .
<?php
phpinfo();
フォルダの構成は以下のようになります。
% tree ✔ 08:40:22
.
├── Dockerfile
└── test
└── index.php
では、以下のコマンドで、Dockerfileをビルドして、docker imageを作成しましょう。
docker build
以下のようにエラー起きます。
どうしてでしょうか?
これは、dockerの仕組みで、どのディレクトリをビルドするのかを指定してあげないといけません。
docker build .
ついでにタグで名前もつけます。タグは-tオプションでつけれます。
docker build -t phpimage .
そうすると、dockerイメージが作成されているはずです。これを元にdockerコンテナを作成し、起動しましょう。
では、作成されたimageを用いて、コンテナを起動させましょう。
今回は、オプションがいっぱいあります。
docker container run -p 3030:80 --name phpcontainer01 phpimage
基本形式は、docker container run phpimageです。
それに、-p コマンドと、–nameコマンドがあります。-pは、接続ポートを指定します。これは、我々が、コンテナに対してアクセスしたいので、指定します。–nameは、コンテナの名前を決めるために指定します。
ポートの意味は、ドキュメントから確認してください。
今回は、3030:80という感じになっています。これは、私たちのパソコンからコンテナに対してアクセスするので、私たちのパソコンは、3030ポートから出入りします。コンテナは、80ポートを開けていて、3030から来たものを通してください。みたいな意味です。
http://localhost:3030こちらにアクセスすると以下のような画面が表示されるはずです。
5.1. おまけ
dockerのコマンドやdockerの実行は、restAPIを返して、dockerデーモンと呼ばれる色々やってくれるところへアクセスします。
画像引用: https://docs.docker.jp/v1.12/engine/understanding-docker.html
docker build .
これ、なんで ” . “をつけているのか気になりませんでしたか?
これは、restAPIってのが肝で、.以下のディレクトリをまとめて、RESTAPIでdockerデーモンさんへ送信します。って意味なんです。
結構大事なんすけど、たとえばディレクトリ構成を以下のように変更してください。
% tree ✔ 09:14:19
.
├── dockertest
│ └── Dockerfile
└── test
└── index.php
こうすると、Dockerfileから見て、index.phpの階層が変わりました。
これを再びイメージビルドするとエラーが起こるので、よって、Dockerfileを編集します。
FROM php:7.4-apache
COPY ../test . ## 変更
これでおっけい。では、docker buildコマンドでビルドしてみます。
docker build ./dockertest
[+] Building 0.5s (6/6) FINISHED
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 72B 0.0s
=> [internal] load metadata for docker.io/library/php:7.4-apache 0.5s
=> [internal] load build context 0.0s
=> => transferring context: 2B 0.0s
=> [1/2] FROM docker.io/library/php:7.4-apache@sha256:c9d7e608f73832673479770d66aacc8100011ec751d1905ff63fae3fe2e0ca6d 0.0s
=> ERROR [2/2] COPY ../test . 0.0s
------
> [2/2] COPY ../test .:
------
Dockerfile:3
--------------------
1 | FROM php:7.4-apache
2 |
3 | >>> COPY ../test .
--------------------
ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref moby::u9ug3hj1ricge1612hoho9va2: "/test": not found
おかしい。”/test”: not foundになっています。
いいえ。。おかしくないんです。これは、dockerにとって正常なエラーなんです。
仕組みはこうです。!!
RESTAPIで送信する際に渡すディレクトリは、上記の写真のように指定したディレクトリ以下になります。つまり、階層を戻って、処理する。というような記述をすると、そんなデータはないですよ。と返ってくるのは当たり前なのです。ですが、結構はまりポイントであると思いますので、言語化しておくことは大事です。
6. 終わりに
Part2はここまでとします。
次回は、 Part3です。お楽しみに!
1 件のコメント