コンテナーとしてのイメージ実行
読む時間の目安: 3 分
前提条件
Java イメージのビルド において説明した手順をひととおり行っていること。
概要
前節においてはサンプルアプリケーションを構築し、イメージビルドに利用する Dockerfile を生成しました。
イメージのビルドにはdocker build
というコマンドを使いました。
イメージのビルドができたので、そのイメージを実行して、アプリケーションが正しく動作することを確認します。
コンテナーというものは、オペレーティングシステム内の通常のプロセスにすぎません。 ただしこのプロセスは他から隔離されていて、独自のファイルシステム、独自のネットワークを持ちます。 またホストからは引き離された独自のプロセスツリーを持ちます。
コンテナー内においてイメージを実行するにはdocker run
コマンドを使います。
docker run
コマンドには 1 つの引数を必要とします。
それはイメージ名です。
ここまでに作り出したイメージを使って、正しく動作することを確認します。
ターミナルから以下のコマンドを実行します。
$ docker run java-docker
このコマンドを実行しても、コマンドプロンプトの入力状態には戻りません。 この理由は、実行したアプリケーションが REST サーバーであって、入ってくる要求を待ち受けるためのループ内で実行されるからです。 つまり OS へ戻る制御はなく、戻るためにはコンテナーを停止させることになります。
さてそこで新たなターミナルを開いて、このサーバーに対してcurl
コマンドを使ってGET
リクエストを行ってみます。
$ curl --request GET \
--url http://localhost:8080/actuator/health \
--header 'content-type: application/json'
curl: (7) Failed to connect to localhost port 8080: Connection refused
上の curl コマンドは、サーバーへの接続が拒否されたために失敗しました。 localhost のポート 8000 には接続できなかったということです。 この動作は期待どおりであって、コンテナーはネットワークも含めて隔離された環境内で実行されているからです。 一度コンテナーを停止させて、今度はローカルネットワーク上にポート 8000 を公開した上で再起動してみます。
コンテナーを停止するにはctrl-c
を入力します。
これによってターミナルのコマンドプロンプトが入力状態に戻ります。
コンテナーのポートを公開するには、docker run
コマンドにおいて--publish
フラグ(あるいは-p
フラグ)を指定します。
--publish
フラグの書式は[ホストポート]:[コンテナーポート]
です。
そこでコンテナー内部のポート 8000 をコンテナー外部のポート 8080 として公開するには、--publish フラグに 8080:8000 と指定します。
コンテナーを起動させ、ポート 8080 をホスト上のポート 8080 として公開します。
$ docker run --publish 8080:8080 java-docker
そこで先ほどの curl コマンドを再度実行してみます。
$ curl --request GET \
--url http://localhost:8080/actuator/health \
--header 'content-type: application/json'
{"status":"UP"}
成功しました。 コンテナー内部で実行されているアプリケーションに対して、ポート 8080 による接続ができました。
ctrl-c を入力してコンテナーを停止します。
デタッチモード実行
ここまではうまくいきました。
もっともこのサンプルアプリケーションはウェブサーバーなので、コンテナーに接続するものではありません。
Docker ではコンテナーをデタッチモード(detached mode)、つまりバックグラウンドで実行することができます。
これを行うには--detach
フラグ、あるいは短く-d
フラグを指定します。
Docker は先ほどと同じようにコンテナーを起動させますが、今回はコンテナーから「デタッチされた」つまり切り離されて実行されるので、ターミナルにプロンプトが戻ってきます。
$ docker run -d -p 8080:8080 java-docker
5ff83001608c7b787dbe3885277af018aaac738864d42c4fdf5547369f6ac752
Docker はバックグラウンドでコンテナーを起動させ、ターミナル上にそのコンテナー ID を出力します。
同じようにコンテナーが適切に動作していることを確認します。 前とまったく同じ curl コマンドを実行してみます。
$ curl --request GET \
--url http://localhost:8080/actuator/health \
--header 'content-type: application/json'
{"status":"UP"}
コンテナーの一覧表示
コンテナーをバックグラウンドで実行したので、コンテナーが実行しているかどうか、他にどんなコンテナーがマシン上で動作しているかは、どうやって調べたらよいでしょう。
それはdocker ps
コマンドを使います。
Linux 上であれば、マシン上のプロセス一覧を確認するには ps コマンドを実行します。
同じように Docker ではdocker ps
を実行します。
このコマンドによって、マシン上で稼働しているコンテナーの一覧が表示されます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5ff83001608c java-docker "./mvnw spring-boot:…" About a minute ago Up About a minute 0.0.0.0:8080->8080/tcp trusting_beaver
docker ps
コマンドは実行中コンテナーに関して、いろいろな情報を表示します。
その情報とは以下です。
コンテナー ID、コンテナー内部で実行しているイメージ、コンテナー起動時に用いられた実行コマンド、コンテナー生成時刻、ステータス、公開ポート、コンテナー名です。
コンテナー名はどうやって決まったんだろうと不思議に思うかもしれません。
コンテナーを起動したときにはコンテナー名を指定したわけではないので、Docker がランダムに名前を生成します。
コンテナー名はこの後すぐに変更していきますが、そのためにはまずコンテナーを停止する必要があります。
コンテナーを停止するにはdocker stop
コマンドを実行します。
このコマンドはそのとおりにコンテナーを停止させます。
この際にはコンテナー名あるいはコンテナー ID を指定します。
$ docker stop trusting_beaver
trusting_beaver
docker ps
コマンドをもう一度実行して、実行中コンテナーの一覧を確認します。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
コンテナーの停止、起動、名前変更
Docker コンテナーは起動させ停止させ、再起動することができます。
コンテナーを停止してもコンテナーが削除されるわけではなく、ステータスが停止となり、コンテナー内のプロセスが停止します。
docker ps
コマンドを実行したときに、出力されるコンテナーはデフォルトでは実行中コンテナーのみです。
--all
または-a
を指定すると、システム上にあるコンテナーすべて、つまり停止、起動にかかわらずすべてが表示されます。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5ff83001608c java-docker "./mvnw spring-boot:…" 5 minutes ago Exited (143) 18 seconds ago trusting_beaver
630f2872ddf5 java-docker "./mvnw spring-boot:…" 11 minutes ago Exited (1) 8 minutes ago modest_khayyam
a28f9d587d95 java-docker "./mvnw spring-boot:…" 17 minutes ago Exited (1) 11 minutes ago lucid_greider
ここまでのコンテナーがいくつか出力されたはずです。 このコンテナーはこれまでに起動し停止し、そのまま削除していないものです。
停止したコンテナーをここで再起動してみましょう。
停止したコンテナーの名前を確認して、restart
コマンドにおけるコンテナー名を書き換えて指定してください。
$ docker restart trusting_beaver
そこで再びdocker ps
コマンドを使ってコンテナー一覧を確認します。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5ff83001608c java-docker "./mvnw spring-boot:…" 10 minutes ago Up 2 seconds 0.0.0.0:8080->8080/tcp trusting_beaver
630f2872ddf5 java-docker "./mvnw spring-boot:…" 16 minutes ago Exited (1) 13 minutes ago modest_khayyam
a28f9d587d95 java-docker "./mvnw spring-boot:…" 22 minutes ago Exited (1) 16 minutes ago lucid_greider
上で再起動したコンテナーはデタッチモードで起動され、ポート 8000 が公開されています。 またコンテナーのステータスを見てみると「Up X seconds」(起動後 X 秒)となっています。 コンテナーを再起動したときには、はじめに起動したときと同じフラグ、同じコマンドによって起動されます。
ではコンテナーすべてを停止して削除します。 そしてランダムな名前になってしまう点を修正していきます。 実行中のコンテナー名を確認してください。 そして以下のコマンドにおけるコンテナー名を、確認したコンテナー名に置き換えてください。
$ docker stop trusting_beaver
trusting_beaver
こうしてコンテナーはすべて停止したので削除します。 コンテナーを削除すると、コンテナー内のプロセスはすでに停止され、コンテナーに対するメタデータも削除されています。
コンテナーを削除するには、docker rm
コマンドにコンテナー名を与えて実行します。
このコマンド 1 つに対して複数のコンテナー名を指定することもできます。
同じように、以下のコマンドにおけるコンテナー名を書き換えて実行してください。
$ docker rm trusting_beaver modest_khayyam lucid_greider
trusting_beaver
modest_khayyam
lucid_greider
再度docker ps --all
コマンドを実行し、コンテナーすべてが削除されていることを確認してください。
それでは、ランダムな名称になる問題を解決します。 コンテナーに名前をつける理由は単純なものです。 どんなコンテナーが実行されているのかがすぐにわかります。 またどんなアプリケーションやサービスが関連づいているのかがわかります。
コンテナー名をつけるにはdocker run
コマンドに--name
フラグをつけます。
$ docker run --rm -d -p 8080:8080 --name springboot-server java-docker
2e907c68d1c98be37d2b2c2ac6b16f353c85b3757e549254de68746a94a8a8d3
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2e907c68d1c9 java-docker "./mvnw spring-boot:…" 8 seconds ago Up 8 seconds 0.0.0.0:8080->8080/tcp springboot-server
より良くなりました。 こうしてコンテナーの識別は、名前を使って簡単に行えるようになりました。
次のステップ
本節ではコンテナーの実行、ポート公開、デタッチモードでの実行を行いました。 またコンテナーの起動、停止、再起動という制御を行いました。 そしてコンテナーに名前づけを行って、識別しやすくしました。
次節ではコンテナー内においてデータベースを実行して、アプリケーションを接続する方法を示します。 以下を参照してください。
フィードバック
本トピック改善のためにフィードバックをお寄せください。 お気づきの点があれば Docker Docs の GitHub リポジトリに issue をあげてください。 あるいは PR の生成 により変更の提案を行ってください。