====== Dcoker コンテナの基本的な利用方法(Run) ======
Docker 20.10.1
--- //[[http://www.y2sunlight.com|y2sunlight]] 2020-12-18//
[[docker:top|Dockerに戻る]]
関連記事
* [[wsl2:ubuntu:docker|WSL2/Ubuntu に Docker をインストールする]]
* Dcoker コンテナの基本的な利用方法(Run)
* [[docker:20:build|Docker コンテナイメージの作成(Bulid)]]
リンク
* [[https://docs.docker.com/|Docker Docs]] --- Dockerドキュメント (本家)
* [[https://docs.docker.jp/engine/reference/commandline/index.html|Docker コマンド]] --- Docker日本語ドキュメント
Apacheコンテナの例を使ってDockerコンテナの基本的な利用方法を説明します。この例で使うApacheコンテナはDockerHubの公開リポジトリ(パブリックリポジトリ)で配布されているものを使用します。コンテナの作成(Build)とDockerHubついては他の章で説明します。
=== 本章の実行環境 ====
* Windows10Pro / WSL2
* Ubuntu 20.04.1 LTS
本章の実行例は WindowsターミナルのUbuntuターミナルで実行しています。dockerの初期設定については、[[wsl2:ubuntu:docker#初期設定|こちら]]を参照して下さい。
----
===== Dockerサービスの管理 =====
==== サービスの起動と停止 ====
WSL2ではサービス管理に systemd ではなくて sysV init を使っています。従ってサービスの起動/停止は systemctl コマンドはなくて、service コマンドを使います。Macや他のLinux環境とは異なりますので注意して下さい。
Dockerサービスの起動、停止は次のコマンドで行います:
$ sudo service docker status # 起動確認
$ sudo service docker start # 開始
$ sudo service docker stop # 停止
$ sudo service docker restert # 再起動
> WSL2では、通常のLinuxのようなブートシーケンスの中でのデーモンの起動は行われません。従って、Dockerを起動するには、常に上の手順が必要になります。詳しくは、本編「WSL2/Ubuntu に memcached サービス をインストールする:サービスの自動起動」を参照して下さい。
\\
==== 構成情報の確認 ====
Docker のバージョン情報を表示するには [[https://docs.docker.jp/engine/reference/commandline/version.html|docker version]] コマンドを、構成情報を表示するには [[https://docs.docker.jp/engine/reference/commandline/info.html|docker info]] コマンドを実行します:
$ docker version # バージョン情報の表示
$ docker info # 構成情報の表示
\\
===== Dockerイメージの取得 =====
==== イメージのダウンロード ====
ここでは、DockerがDockerHubで公式に公開しているApacheのイメージを使用します。
* https://hub.docker.com/_/httpd
[[https://docs.docker.jp/engine/reference/commandline/pull.html|docker pull]] コマンドでApache(httpd)をダウンロードします。
$ docker pull httpd
実行例:
$ docker pull httpd
Using default tag: latest
latest: Pulling from library/httpd
6ec7b7d162b2: Pull complete
17e233bac21e: Pull complete
130aad5bf43a: Pull complete
81d0a34533d4: Pull complete
da240d12a8a4: Pull complete
Digest: sha256:a3a2886ec250194804974932eaf4a4ba2b77c4e7d551ddb63b01068bf70f4120
Status: Downloaded newer image for httpd:latest
docker.io/library/httpd:latest
\\
==== Dockerイメージとは ====
ここでダウンロードしたイメージは「Dockerイメージ」と呼ばれ、親子関係のある複数の層(レイヤ)が透過的に重なり1つのファイルシステムを構成しているものです。各レイヤはファイルシステムやメタ情報を保持していて、その中に実行するプログラムやライブラリも含まれます。
この Docker イメージが、Docker エンジンによって Docker コンテナとして実行されると、Linux の提供する名前空間(namespace)や cgroup によって隔離された特別な状態のプロセスとして起動されます。
Dockerイメージについては、以下を参照して下さい。非常に丁寧に解説されています:
* [[https://qiita.com/zembutsu/items/24558f9d0d254e33088f|Dockerイメージの理解を目指すチュートリアル]]
\\
==== イメージのレイヤ情報出力 ====
[[https://docs.docker.jp/engine/reference/commandline/history.html|docker history]] コマンドは、Docker イメージをどのように構築したかを調べることができます。このコマンドは、Docker イメージの各レイヤの情報を出力します。
上でダウンロードしたhttpdのレイヤの情報を出力すると:
$ docker image history httpd
IMAGE CREATED CREATED BY SIZE COMMENT
dd85cdbb9987 6 days ago /bin/sh -c #(nop) CMD ["httpd-foreground"] 0B
6 days ago /bin/sh -c #(nop) EXPOSE 80 0B
6 days ago /bin/sh -c #(nop) COPY file:c432ff61c4993ecd… 138B
6 days ago /bin/sh -c #(nop) STOPSIGNAL SIGWINCH 0B
6 days ago /bin/sh -c set -eux; savedAptMark="$(apt-m… 60.9MB
6 days ago /bin/sh -c #(nop) ENV HTTPD_PATCHES= 0B
6 days ago /bin/sh -c #(nop) ENV HTTPD_SHA256=740eddf6… 0B
6 days ago /bin/sh -c #(nop) ENV HTTPD_VERSION=2.4.46 0B
6 days ago /bin/sh -c set -eux; apt-get update; apt-g… 7.38MB
6 days ago /bin/sh -c #(nop) WORKDIR /usr/local/apache2 0B
6 days ago /bin/sh -c mkdir -p "$HTTPD_PREFIX" && chow… 0B
6 days ago /bin/sh -c #(nop) ENV PATH=/usr/local/apach… 0B
6 days ago /bin/sh -c #(nop) ENV HTTPD_PREFIX=/usr/loc… 0B
7 days ago /bin/sh -c #(nop) CMD ["bash"] 0B
7 days ago /bin/sh -c #(nop) ADD file:3a7bff4e139bcacc5… 69.2MB
* 出力順は、降順で新しいレイヤ先になります。
* 各行の''CREATED BY'' がレイヤが作成された時に実行されたコマンドです。
* ''CREATED BY'' を省略無しで出力するには ''--no-trunc=true'' を指定しますが、大量に表示されるので、ファイルにリダイレクトして見た方が良いです。
\\
==== イメージの詳細情報の表示 ====
イメージに関する全ての情報を取得するには、[[https://docs.docker.jp/engine/reference/commandline/inspect.html|docker inspect]] コマンドを利用します。
$ docker inspect httpd
上の例は、全ての詳細情報を表示しますが、次の例のように情報の一部を検索することも出来ます。下の例では、イメージの持つコマンドを検索しています。
docker inspect httpd --format='{{.Config.Cmd}}'
[httpd-foreground]
この例から、httpd イメージのコンテナを実行すると ''httpd-foreground'' が起動されるのが分かります。
\\
===== イメージの操作 =====
Dockerイメージの一覧を表示するには [[https://docs.docker.jp/engine/reference/commandline/images.html|docker images]] を使用します。
実行例:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest dd85cdbb9987 6 days ago 138MB
hello-world latest bf756fb1ae65 11 months ago 13.3kB
Dockerイメージを削除するには [[https://docs.docker.jp/engine/reference/commandline/rmi.html|docker rmi]] を使用します。
実行例:
$ docker rmi httpd
Untagged: httpd:latest
Untagged: httpd@sha256:a3a2886ec250194804974932eaf4a4ba2b77c4e7d551ddb63b01068bf70f4120
Deleted: sha256:dd85cdbb99877b73f0de2053f225af590ab188d79469eebdb23ec2d26d0d10e8
Deleted: sha256:bc2085990715d2d1ac2179131969b293821dbcf7f0538eaeb3bc3bb6d5645a13
Deleted: sha256:a11bf2367d443697ca6267194a18b31289b59b677133e6482779851fa33992df
Deleted: sha256:388a801aa9f7953143fc154e7bc16dd5b696d2f3578a054b0b804557a8d89d74
Deleted: sha256:37495edb13f558e001fba79f653b38ac3cad5e29f189c1e20501f3f6d5326fdc
Deleted: sha256:87c8a1d8f54f3aa4e05569e8919397b65056aa71cdf48b7f061432c98475eee9
その他、Dockerのイメージ用のコマンドは、以下を参照して下さい。
* [[https://docs.docker.jp/engine/reference/commandline/index.html#id8|Docker イメージ用コマンド]] --- Dockerドキュメント(日本語)
\\
===== コンテナの起動 =====
コンテナの起動は [[https://docs.docker.jp/engine/reference/commandline/run.html|docker run]] コマンドで行います。以下は、先にダウンロードしたapacheイメージをコンテナとして実行した例です:
$ docker run -d -p 8080:80 httpd:latest
fec87985e9846942efee7de5d80b4a8aee83de7276b69b7e97c6425410afeb70
* ''-d'' --- コンテナをバックグラウンドで実行
* ''-p'' --- ポートフォワードの指定(左がホスト側:8080、右がコンテナ側:80)
* イメージの指定は「イメージID」または「リポジトリ:タグ名」で指定
''docker run'' コマンドはDockerイメージからコンテナを作成し開始するコマンドです。似たようにコマンドに、コンテナを作成だけをする [[https://docs.docker.jp/engine/reference/commandline/create.html|docker create]] コマンド、コンテナを開始する [[https://docs.docker.jp/engine/reference/commandline/start.html|docker start]] コマンドがあります。
''netstat'' コマンドを実行し、apache が動作しているか確認します:
$ netstat -an|grep 8080
tcp6 0 0 :::8080 :::* LISTEN
''curl'' で apache にアクセスしてみます:
$ curl http://localhost:8080/
It works!
次に、WindowsターミナルでPowerShellを開き、''netstat'' コマンドを使って、同じポート番号(8080)がWindows側で開いているか確認します:
>netstat -an|Select-String "8080"
TCP [::1]:8080 [::]:0 LISTENING
Windows側のブラウザを開き、以下のURLにアクセスしてすると、お馴染みの「''It works!''」が表示されます。
http://localhost:8080/
この例で分かるように、コンテナで起動しているApacheのポート(80)は、ホスト側(Ubuntu)のポート(8080)にフォワードされ、そのフォワードされたポートは、WSL2の仮想ネットワークを通して、Windows側のlocalhostでリスニングできるような仕組みになっています。結局、WSL2では、コンテナ側からホスト側にフォワードしたのと同じポード番号がWindowsのlocalhostで開いていることになります。
\\
===== コンテナの操作 =====
[[https://docs.docker.jp/engine/reference/commandline/ps.html|docker ps]] コマンドは稼働中のコンテナの一覧を表示します。''-a'' オプションを付けると、停止中のコンテナも含めて全てのコンテナの一覧を表示します。
$ docker ps # 稼働中のコンテナの一覧
$ docker ps -a # 全てのコンテナの一覧
実行例:
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fec87985e984 httpd:latest "httpd-foreground" 47 minutes ago Exited (0) 48 seconds ago objective_mahavira
以下のコマンドは、コンテナの開始、停止、強制終了、削除を行います:
* [[https://docs.docker.jp/engine/reference/commandline/start.html|docker start]] --- コンテナの開始
* [[https://docs.docker.jp/engine/reference/commandline/stop.html|docker stop]] --- コンテナの停止
* [[https://docs.docker.jp/engine/reference/commandline/kill.html|docker kill]] --- コンテナの強制終了
* [[https://docs.docker.jp/engine/reference/commandline/rm.html|docker rm]] --- コンテナの削除
実行例:
$ docker start fec87985e984 # 開始
$ docker stop fec87985e984 # 停止
$ docker kill fec87985e984 # 強制終了
$ docker rm fec87985e984 # 削除
その他、Dockerのコンテナ用のコマンドは、以下を参照して下さい。
* [[https://docs.docker.jp/engine/reference/commandline/index.html#id9|Docker コンテナ用コマンド]] --- Dockerドキュメント(日本語)
\\
===== バインドマウントの利用 =====
==== バインドマウントとは ====
[[https://matsuand.github.io/docs.docker.jp.onthefly/storage/bind-mounts/|バインドマウント]]とは、ホストマシン上のファイルやディレクトリをコンテナー内にマウントする機能です。そのファイルやディレクトリは、ホストマシン上の絶対パスにより参照できます。バインドマウントは非常に性能の良いものですが、ホストマシンのファイルシステムに依存するものとなります。新たに Docker アプリケーションを開発する場合は、バインドマウントにかわって 名前つき[[https://matsuand.github.io/docs.docker.jp.onthefly/storage/volumes/|ボリューム]]の利用を考えるのも良いかもしれません。
\\
==== バインドマウントの例 ====
バインドマウント(bind mounts)の例として、Apache コンテナのドキュメントルートをホスト側にマウントします。
まず、準備としてホスト側で ホームディレクトリ下に新しいディレクトリ(''htdocs'')を作成し、そこをマウント元にします。
$ cd ~
$ mkdir htdocs
$ cd htdocs
新しいディレクトリ(''~/htdocs'')に移動して、''index.html'' を作成します:
Hello from Docker!
今度は、apache の ''DocumentRoot'' を探すために、httpd コンテナを開始して bash を実行します:
$ docker run -it httpd bash
* ''-i'' --- コンテナの STDIN にアタッチ
* ''-t'' --- 疑似ターミナルの割り当て
コンテナ内で ''httpd.conf'' から ''DocumentRoot'' の設定を検索します:
# cat /usr/local/apache2/conf/httpd.conf|grep "^DocumentRoot"
DocumentRoot "/usr/local/apache2/htdocs"
コンテナ内での操作が終了したら ''exit'' で終了します。
=== Apacheコンテナの起動 ===
Apache のドキュメントルート( ''/usr/local/apache2/htdocs'' )をホスト側の( ''~/htdocs'' )にマウントしてコンテナを開始します(ディレクトリは ''~/htdocs'' で作業しているものをします):
$ docker run -d -p 8080:80 -v $(pwd):/usr/local/apache2/htdocs httpd
* ''-d'' --- コンテナをバックグラウンドで実行
* ''-p'' --- ポートフォワードの指定(左がホスト側:8080、右がコンテナ側:80)
* ''-v'' --- ホスト側の現在のカレントディレクトリ(''$(pwd)'')をコンテナの ''/usr/local/apache2/htdocs'' にバインドマウント
この例では、''-v'' フラグを使ってバインドマウントを行っています。この習慣は長らく Docker で使用されて来ましたが、最近は ''--mount'' の利用が推奨されています。以下の例は、上の ''-v''フラグによる例と同一の結果になります。
$ docker run -d -p 8080:80 --mount type=bind,source=$(pwd),target=/usr/local/apache2/htdocs httpd
両者の違いは次の通りです。
* ''-v''フラグを使ってファイルやディレクトリをバインドマウントした際に、それがホスト上に存在していなかった場合、そのマウントエンドポイントが常にディレクトリとして生成されます。
* ''--mount'' を使ってバインドマウントした時は、それが存在していなかった場合、ディレクトリの自動生成は発生せず、エラーが出力されます。
\\