🐋

【初学者向け】Dockerコンテナ基本操作

2024/05/04に公開

はじめに

この記事は、以前私が書いた「【初学者向け】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公式ドキュメントを有志の方々が日本語に翻訳してくれているものです。

https://docs.docker.jp/engine/reference/commandline/index.html

公式による最新のドキュメントを確認したい人は、以下のリンクから飛ぶことができます。

https://docs.docker.com/

1.コンテナの起動から破棄までの流れ

まず、コンテナが起動するまでの流れを追っていきたいと思います。また、今回はhttpdイメージを利用します。httpdの使い方などは以下のサイトを確認してください。

https://hub.docker.com/_/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 pulldocker createdocker 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.4docker 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 rundocker 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+PCtrl+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+PCtrl+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+PCtrl+Qを入力してデタッチできるのはこのオプション達を指定しているからです。

「-i」オプションは入出力及びエラー出力をコンテナに対して結びつける役割を持ち、文字がコンテナに渡され、コンテナからの出力が画面に表示されるようになります。「-i」オプションを指定しないと、キー入力はコンテナに伝わらないためこうしたキー入力が効きません。そしてコンテナからの出力も届かないため、画面に各種ログが表示されることもありません。

「-t」オプションはpseudo-TTYと呼ばれる疑似端末を有効にする役割を持ちます。疑似端末は、カーソルキーやエスケープキー、Ctrlキーなどで操作するためのものです。このオプションを指定せず、「-i」オプションのみだとこれらのキーが使えず、Ctrl+PCtrl+Qキーが効きません。

コンテナを端末から操作する必要がないのであれば、「-i」や「-t」のオプションは必要ありません。逆に、アタッチするなどして端末から操作したい場合は、「-i」や「-t」オプションを指定する必要があります。

3.コンテナのメンテナンス

作業していく中で、動作中もしくは停止中のコンテナに入り込んでファイルを確認したり編集したり、インストールしたりしたくなることがあると思います。ここからは、そうしたコンテナのメンテナンス方法を説明します。

コンテナに入り込んで何か操作したい時は、「コンテナの中でシェルを実行し、そのシェルを通じてさまざまな操作をする」という考え方があります。ここで、シェルはキーボードからの操作を読み取り、それを解釈実行して結果を画面に表示するプログラムのことを指します。/bin/bashなどを知っていると言う人もいるのではないでしょうか。

コンテナ内部でシェルを実行するにはコンテナが動いているかどうかによって、次のいずれかの方法を採ります。

停止中もしくはまだ作られていない時 動作中の時
docker runの引数に、/bin/sh/bin/bashなどのシェルを指定し、本来実行される既定のコマンドの代わりにこれらのシェルが起動されるようにします。この時にキー操作をする必要があるため、「-i」オプションを忘れずに指定しましょう。 docker execコマンドを使います。docker exec -it コンテナ名 /bin/bashのようにすると、現在コンテナ内で実行されているコマンドとは別にシェルが起動します。

まずは、コンテナが停止している場合から確かめます。ここでも、これまで使ってきたのと同じhttpdイメージを使います。

停止中のコンテナでシェルを実行する

  1. /bin/bashを実行する

次のように入力して、/bin/bashを実行します。

docker run --name my-apache-app -it httpd:2.4 /bin/bash

実行すると「root@コンテナID:/usr/local/apache2#」のように表示され、このコンテナの中に入ることが出来ます。

  1. コマンドを入力する

ここで何かコマンドを入力すると、コンテナの中で実行することが出来ます。例えば、lsコマンドを実行すると、コンテナ内のファイルー覧を閲覧できます。

  1. コンテナの中と外を行き来する

停止中のコンテナをメンテナンスした後に、Ctrl+PCtrl+Qを押してデタッチしてみましょう。

デタッチしたため、端末での操作はDockerホストに移りました。つまり、以降の操作はDockerホスト側での操作となります。この時、コンテナはまだ動いています。docker attachコマンドを使用すれば、コンテナに端末を再接続でき、操作できます。

このようにして、停止中のコンテナをメンテナンスすることが出来ます。

  1. シェルを終了する

ここで、exitと入力して実行してみましょう。これは、シェル(今回の場合では、実行している「/bin/bash」のこと)を終了させることを意味します。実行すると、次のようにコンテナの外に戻ります。

  1. コンテナが終了したことを確認する

Dockerでは、docker runコマンド(docker startコマンドも同様)が終了した時は、コンテナ自体が停止します。上記の操作によって、プログラムは終了していることから、コンテナも終了します。docker ps -aで確認するとSTATUSがExitedになっており、終了していることがわかりました。

  1. コンテナの破棄

作業が終わったら、コンテナを削除しておきましょう。

実行中のコンテナでシェルを実行する

次は、動作しているコンテナに対してシェル操作する方法を説明します。言い換えると、「-d」オプションを指定してデタッチモードで動作しているコンテナに対してシェル操作する方法です。

  1. コンテナをデタッチモードで起動する

まず、次のようにhttpdコンテナを「-dit」オプションを付けて実行して起動します。

docker run --name my-apache-app -dit -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
  1. コンテナの状態を確認する

docker ps -aでコンテナの状態を確認するとSTATUSがUpになっており、コンテナが稼働していることがわかります。

また、COMMANDを確認すると「httpd-foreground」と記述されています。これはhttpdイメージの製作者が設定した既定の実行コマンドであり、このコマンドがApacheを内部で起動しています。

  1. シェルを起動する

では、シェルを起動してみましょう。
実行中のコンテナでシェルを起動するにはdocker runコマンドではなく、docker execコマンドを用います

docker exec -it my-apache-app /bin/bash

コマンドを実行すると、以下のようになりました。

ここでは割愛しますが、停止中のコンテナでシェルを実行した場合と同様に、各種コマンドを入力したりデタッチしたりすることももちろん可能です。

  1. シェルを終了する

ここで、exitを入力してシェルを終了させましょう。

  1. コンテナの状態を確認する

docker ps -aで確認すると、STATUSがUpのままであり、コンテナがまだ稼働していることがわかります。

なぜコンテナが終了していないかというと、終了したのはあくまでもdocker execで実行した/bin/bashであり、docker runで実行されている「httpd-foreground」が終了したわけではないからです。

  1. コンテナの破棄

作業が終わったら、コンテナを削除しましょう。ここではコンテナがまだ稼働しているため、必ずコンテナを停止した後に破棄しましょう。

docker stop my-apache-app
docker rm my-apache-app

docker rundocker execの違い

このようにdocker execを使えば、稼働中のコンテナに対して影響を与えることなく、コンテナ内に入り込んで作業を行うことができます。docker rundocker execの違いはこのようになっています。

コマンド コンテナの状態 シェル終了時
docker run 停止時 コンテナ終了
docker exec 稼働時 稼働したまま

さいごに

ここまで記事を読んでくださり、ありがとうございました!

今回は、私がDockerを利用していく中で重要だと感じたDockerコンテナの基本操作方法についてまとめてみました。

まだまだ経験が浅く使い慣れていないですが、Dockerをより理解するために突き進んでいきたいと思います!

皆さんも素敵なハッピーDockerライフを!!!🌸

GitHubで編集を提案

Discussion