【初学者向け】Dockerコンテナ基本操作
はじめに
この記事は、以前私が書いた「【初学者向け】DockerでWebサーバーを起動する」という記事の内容を踏まえて、Dockerの基本操作についてまとめたものです。
私の動作環境
- Docker Desktop 4.21.1 (114176)
- Docker Engine 24.0.2
- Docker Compose v2.19.1
- MacOS Sonoma 14.4.1
Dockerコマンド一覧
Dockerのコマンド一覧は、以下のサイトに記載されています。このサイトは、Docker公式ドキュメントを有志の方々が日本語に翻訳してくれているものです。
公式による最新のドキュメントを確認したい人は、以下のリンクから飛ぶことができます。
1.コンテナの起動から破棄までの流れ
まず、コンテナが起動するまでの流れを追っていきたいと思います。また、今回はhttpdイメージを利用します。httpdの使い方などは以下のサイトを確認してください。
私は以前、Docker上でWebサーバーを起動した際に以下のようにdocker run
コマンドを利用しました。
docker run -dit --name my-apache-app -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
この時に使用したdocker run
コマンドは、docker pull
、docker create
、docker start
の三つのコマンドを複合した機能を持つコマンドであり、上のコマンドと下の三つのコマンドは同じ意味を持ちます。
docker pull httpd:2.4
docker create -dit --name my-apache-app -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
docker start my-apache-app
この三つのコマンドをそれぞれ見ていきます。
docker pull
docker pull
コマンドはイメージを取得する際に用いるものであり、
docker pull イメージ名orイメージID
といった書式で使用できます。
また、先ほどのdocker pull httpd:2.4
はhttpdの「2.4」というバージョンのイメージをダウンロードするということを表しています。
最新版を意味する「latest」
ここでdocker pull httpd:2.4
をdocker pull httpd
のようにタグ名を省略した場合、最新版を意味する「latest」というタグがつけられたとみなされ、最新のバージョンのイメージがインストールされます。
どうしても特定のバージョンを使いたい時以外は、タグを省略しても良さそうです。
docker create
docker create
コマンドはイメージからコンテナを作成する際に用いるものであり、
docker create オプション イメージ名orイメージID 実行したいコマンド
といった書式で使用できます。
今回のdocker create -dit --name my-apache-app -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
は実行したいコマンドを省略しています。
その代わりにhttpdコンテナの制作者が定めたWebサーバーの通信をするためのコマンドが自動的に実行され、自動的にサーバーが立ちます。
また、上記のコマンドでは、「-dit」、「--name」、「-p」、「-v」の四つのオプションが使用されています。
「-dit」オプション
「-dit」オプションはコンテナをバックグラウンドで動かすために指定しています。
このオプションに関しては、後ほど詳しく説明します。
「--name」オプション
「--name」オプションはコンテナ名をつける際に使用します。
先ほどのコマンドでは、--name my-apache-app
とすることで作成したコンテナを「my-apache-app」というコンテナ名で利用できるようにしています。
「-p」オプション
「-p」オプションはポート番号をマッピングする際に用いるものであり、
-p ホストのポート番号:コンテナのポート番号
といった書式で使用できます。
先ほどのコマンドでは「-p 8080:80」と指定しており、DockerホストのTCPポート8080番をコンテナ内のTCPポート80番に結びつけています。
これをポート番号のマッピングといいます。この設定を行ったため、Dockerホストの8080番に送られた通信はコンテナ内の80番に送られ、コンテナ内で立ち上げているApacheサーバーに届くようになります(リクエスト)。
逆に、コンテナ内のWebサーバのレスポンスもDockerホストから確認できます。これにより、「http://DockerホストのIP:8080/」でアクセスすると、コンテナ内のApacheサーバが公開している内容が見えるようになります。実際に私は以前このURLにアクセスしてWebサーバーが起動していることを確認しました。
Dockerでは「-p」オプションを指定しない限り、DockerホストとDockerコンテナとの通信はつながりません。Dockerホストを通じてDockerコンテナ内で動いているプログラムと通信するには、「-p」オプションの設定が必要になります。
ちなみにマッピングの状態は、docker port
コマンドで確認できます。
「-v」オプション
「-v」オプションは、コンテナの特定のディレクトリにホストのディレクトリをマウントする際に用いるものであり、
-v ホストのディレクトリ:コンテナのディレクトリ
といった書式で使用できます。
先ほどのコマンドでは、-v "$PWD":/usr/local/apache2/htdocs/
といったように「-v」オプションを指定しており、$PWDの値をコンテナの/usr/local/apache2/htdocs/に割り当てています。
ここで、$PWD
はdockerコマンドを入力したホスト側のカレントディレクトリを示す環境変数であり、/usr/local/apache2/htdocs
はコンテナ側のマウント先のディレクトリです。
docker start
docker create
で作成したコンテナはまだ何も動作していません。
そこでdocker start
コマンドを使用することでコンテナを動かすことができます。
docker start
コマンドは、
docker start コンテナ名orコンテナID
といった書式で使用できます。
先ほどのコマンドでは、docker start my-apache-app
といったようにコンテナ名を指定することで、作成したコンテナを起動します。
ここまで、「pull」、「create」、「start」の三つのコマンドについて説明しましたが、単一で動かすことはほとんどないと思われます。複合した機能を持つdocker run
コマンドについての理解を深めておくと良さそうですね。
docker stop
docker run
やdocker start
コマンドで稼働したコンテナはdocker stop
コマンドを使用することで停止することができます。
docker stop
コマンドは、
docker stop コンテナ名orコンテナID
といった書式で使用できます。
上記のコマンドを実行した後にdocker stop my-apache-app
といったようにコンテナ名を指定することで、稼働中のコンテナを停止させることができます。
これで、コンテナの起動から破棄までの流れの確認は以上です。
2.コンテナのデタッチとアタッチ
今、立ち上げたコンテナはバックグラウンドで動いていると思います。なぜなら、「-dit」オプションを指定しているからです。
では、「-dit」オプションをつけずに実行すると、どうなるのか試してみましょう。
docker run --name my-apache-app -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
実行すると、次のようにログが表示され、キー入力を受け付けなくなります。
ここで、Ctrl+C
を押すとコンテナが停止し、キー入力を受け付けられるようになります。
docker ps
コマンドに「-a
」オプションを指定すると、稼働中ではないものも含むすべてのコンテナ一覧を確認することができます。それを用いて確認するとSTATUSがExitedになっていることから、コンテナが停止していることが確認できました。
このように「-dit」オプションを指定しなかった場合、コンテナをバックグラウンドで動かすことが出来ないということがわかります。
コンテナの動作をバックグラウンドで行う必要があるなら「-dit」オプションをつけないといけないと言うことを覚えておきましょう。
また、ここで停止したコンテナは使わないのであれば破棄しましょう。
docker rm my-apache-app
「-dit」は、「-d」「-i」「-t」の3つのオプションの組み合わせです。「-d」が、端末から切り離してバックグラウンドで実行することを指定するオプションであり、「-i」と「-t」はコンテナを端末(キーボードとディスプレイ)から操作するためのオプションです。
「-d」で端末と切り離した状態で実行している状態を「デタッチ」と言います。逆に、先ほど「-dit」を省略して実行した時のように、端末と接続した状態で実行することを「アタッチ」と言います。
「-d」を指定しない時、つまりアタッチモードの時は端末と接続された状態なので、端末からの操作はコンテナ内で実行されているコマンドに対して有効になります。
デタッチの時は端末と切り離されているので、コンテナ内で実行されているコマンドに対して何かキー操作することはできません。
また、デタッチの状態とアタッチの状態は、実行中に切り替えることができます。
デタッチへの切り替え | アタッチへの切り替え |
---|---|
Ctrl+P →Ctrl+Q の順に入力 |
docker attach コマンドの入力 |
では実際に切り替えを試してみましょう。
「-d」オプションを指定せずに、「-it」のみでコンテナを実行します。
docker run -it --name my-apache-app -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
「-d」オプションを指定していないため、コンテナはアタッチされている状態で動作します。そのため、実行画面でCtrl+P
、Ctrl+Q
を入力してデタッチすると、コマンド入力できるようになりました。
docker ps -a
で確認すると、STATUSがUpになっていることから、デタッチして端末から切り離したとしてもコンテナが実行中であることも確認できます。
次はアタッチをしてみましょう。docker attach
コマンドは、
docker attach コンテナ名orコンテナID
といった書式で使用できます。
これにより、端末がコンテナと結びつけられます。本来はアタッチをした後にコマンド入力を受け付けるようになるのですが、httpdコンテナは例外であり、再度アタッチすることができなくなっています。
そのため、docker ps -a
で確認するとSTATUSがExitedになっており、コマンドが終了していることが確認できます。
ここで、停止したコンテナはdocker rm my-apache-app
で破棄しておきましょう。
ここで「-i」オプションと「-t」オプションの詳しい説明をします。
先ほど、アタッチしている状態でCtrl+P
、Ctrl+Q
を入力してデタッチできるのはこのオプション達を指定しているからです。
「-i」オプションは入出力及びエラー出力をコンテナに対して結びつける役割を持ち、文字がコンテナに渡され、コンテナからの出力が画面に表示されるようになります。「-i」オプションを指定しないと、キー入力はコンテナに伝わらないためこうしたキー入力が効きません。そしてコンテナからの出力も届かないため、画面に各種ログが表示されることもありません。
「-t」オプションはpseudo-TTYと呼ばれる疑似端末を有効にする役割を持ちます。疑似端末は、カーソルキーやエスケープキー、Ctrlキーなどで操作するためのものです。このオプションを指定せず、「-i」オプションのみだとこれらのキーが使えず、Ctrl+P
、Ctrl+Q
キーが効きません。
コンテナを端末から操作する必要がないのであれば、「-i」や「-t」のオプションは必要ありません。逆に、アタッチするなどして端末から操作したい場合は、「-i」や「-t」オプションを指定する必要があります。
3.コンテナのメンテナンス
作業していく中で、動作中もしくは停止中のコンテナに入り込んでファイルを確認したり編集したり、インストールしたりしたくなることがあると思います。ここからは、そうしたコンテナのメンテナンス方法を説明します。
コンテナに入り込んで何か操作したい時は、「コンテナの中でシェルを実行し、そのシェルを通じてさまざまな操作をする」という考え方があります。ここで、シェルはキーボードからの操作を読み取り、それを解釈実行して結果を画面に表示するプログラムのことを指します。/bin/bash
などを知っていると言う人もいるのではないでしょうか。
コンテナ内部でシェルを実行するにはコンテナが動いているかどうかによって、次のいずれかの方法を採ります。
停止中もしくはまだ作られていない時 | 動作中の時 |
---|---|
docker run の引数に、/bin/sh や/bin/bash などのシェルを指定し、本来実行される既定のコマンドの代わりにこれらのシェルが起動されるようにします。この時にキー操作をする必要があるため、「-i」オプションを忘れずに指定しましょう。 |
docker exec コマンドを使います。docker exec -it コンテナ名 /bin/bash のようにすると、現在コンテナ内で実行されているコマンドとは別にシェルが起動します。 |
まずは、コンテナが停止している場合から確かめます。ここでも、これまで使ってきたのと同じhttpdイメージを使います。
停止中のコンテナでシェルを実行する
- /bin/bashを実行する
次のように入力して、/bin/bashを実行します。
docker run --name my-apache-app -it httpd:2.4 /bin/bash
実行すると「root@コンテナID:/usr/local/apache2#」のように表示され、このコンテナの中に入ることが出来ます。
- コマンドを入力する
ここで何かコマンドを入力すると、コンテナの中で実行することが出来ます。例えば、ls
コマンドを実行すると、コンテナ内のファイルー覧を閲覧できます。
- コンテナの中と外を行き来する
停止中のコンテナをメンテナンスした後に、Ctrl+P
、Ctrl+Q
を押してデタッチしてみましょう。
デタッチしたため、端末での操作はDockerホストに移りました。つまり、以降の操作はDockerホスト側での操作となります。この時、コンテナはまだ動いています。docker attach
コマンドを使用すれば、コンテナに端末を再接続でき、操作できます。
このようにして、停止中のコンテナをメンテナンスすることが出来ます。
- シェルを終了する
ここで、exit
と入力して実行してみましょう。これは、シェル(今回の場合では、実行している「/bin/bash」のこと)を終了させることを意味します。実行すると、次のようにコンテナの外に戻ります。
- コンテナが終了したことを確認する
Dockerでは、docker run
コマンド(docker start
コマンドも同様)が終了した時は、コンテナ自体が停止します。上記の操作によって、プログラムは終了していることから、コンテナも終了します。docker ps -a
で確認するとSTATUSがExitedになっており、終了していることがわかりました。
- コンテナの破棄
作業が終わったら、コンテナを削除しておきましょう。
実行中のコンテナでシェルを実行する
次は、動作しているコンテナに対してシェル操作する方法を説明します。言い換えると、「-d」オプションを指定してデタッチモードで動作しているコンテナに対してシェル操作する方法です。
- コンテナをデタッチモードで起動する
まず、次のようにhttpdコンテナを「-dit」オプションを付けて実行して起動します。
docker run --name my-apache-app -dit -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
- コンテナの状態を確認する
docker ps -a
でコンテナの状態を確認するとSTATUSがUpになっており、コンテナが稼働していることがわかります。
また、COMMANDを確認すると「httpd-foreground」と記述されています。これはhttpdイメージの製作者が設定した既定の実行コマンドであり、このコマンドがApacheを内部で起動しています。
- シェルを起動する
では、シェルを起動してみましょう。
実行中のコンテナでシェルを起動するにはdocker run
コマンドではなく、docker exec
コマンドを用います。
docker exec -it my-apache-app /bin/bash
コマンドを実行すると、以下のようになりました。
ここでは割愛しますが、停止中のコンテナでシェルを実行した場合と同様に、各種コマンドを入力したりデタッチしたりすることももちろん可能です。
- シェルを終了する
ここで、exit
を入力してシェルを終了させましょう。
- コンテナの状態を確認する
docker ps -a
で確認すると、STATUSがUpのままであり、コンテナがまだ稼働していることがわかります。
なぜコンテナが終了していないかというと、終了したのはあくまでもdocker exec
で実行した/bin/bash
であり、docker run
で実行されている「httpd-foreground」が終了したわけではないからです。
- コンテナの破棄
作業が終わったら、コンテナを削除しましょう。ここではコンテナがまだ稼働しているため、必ずコンテナを停止した後に破棄しましょう。
docker stop my-apache-app
docker rm my-apache-app
docker run
とdocker exec
の違い
このようにdocker exec
を使えば、稼働中のコンテナに対して影響を与えることなく、コンテナ内に入り込んで作業を行うことができます。docker run
とdocker exec
の違いはこのようになっています。
コマンド | コンテナの状態 | シェル終了時 |
---|---|---|
docker run |
停止時 | コンテナ終了 |
docker exec |
稼働時 | 稼働したまま |
さいごに
ここまで記事を読んでくださり、ありがとうございました!
今回は、私がDockerを利用していく中で重要だと感じたDockerコンテナの基本操作方法についてまとめてみました。
まだまだ経験が浅く使い慣れていないですが、Dockerをより理解するために突き進んでいきたいと思います!
皆さんも素敵なハッピーDockerライフを!!!🌸
Discussion