コンテナで Hello world

Docker とは一体何なのでしょうか?

Docker はアプリケーションをコンテナ内に作成した世界で実行可能にします。コンテナ内でアプリケーションを実行するには、docker run コマンドを実行するだけです。

注釈

Docker システムの設定によっては、ガイドにおける各ページの docker コマンドで sudo が必要になる場合があります。この挙動を回避するには、システム管理者に対して docker という名称の Unix グループを作成し、そこにユーザを追加するようご依頼ください。

Hello world の実行

まずは、試してみましょう。

$ docker run ubuntu:14.04 /bin/echo 'Hello world'
Hello world

これが初めて起動したコンテナです!

一体何が起こったのでしょうか? docker run コマンドが処理した内容を見ていきましょう。

まず docker バイナリに対して、処理したいコマンド run (「実行」の意味)を指定します。コマンド docker run の組み合わせは、コンテナを実行 (run)するという意味です。

次に続くのはイメージ ubuntu の指定です。これは、私達が実行したコンテナの元になるモノです。これを Docker ではイメージと呼びます。この例では、Ubuntu オペレーティング・システムのイメージを使いました。

イメージを指定すると、Docker はまず 自身の Docker ホスト上でイメージを探します。もしイメージが見つからなければ、パブリック・イメージ・レジストリの Docker Hub からイメージをダウンロードします。

次に、新しいコンテナ内で何のコマンドを実行するか Docker に対して命令します。

/bin/echo 'Hello world'

コンテナが起動すると、Docker は新しい Ubuntu 環境を作り、その中で /bin/echo コマンドを実行します。コマンドライン上では、次の結果が表示されます:

Hello world

それでは、表示した後のコンテナはどのような状況でしょうか。Docker コンテナが実行されていたのは、指定したコマンドを処理していた間のみです。この例では、Hello world を画面に表示した後、直ちにコンテナが停止しました。

インタラクティブなコンテナ

もう一度 docker run コマンドを実行しましょう。今度はコンテナ内で新しいコマンドを指定します。

$ docker run -t -i ubuntu:14.04 /bin/bash
root@af8bae53bdd3:/#

ここでは再び docker run コマンドを実行し、ubuntu イメージを起動しました。しかし、今回は -t-i の2つのフラグも付けています。-t フラグは新しいコンテナの中に疑似ターミナル (pseudo-tty) を割り当てます。-i フラグはコンテナの標準入力 (STDIN)を取得し、双方向に接続できるようにします。

また、コンテナ実行時に /bin/bash という新しいコマンドも指定しました。これは、コンテナの中で Bash シェルを起動しようとします。

そして、コンテナが起動したら、次のようなコマンド・プロンプトが表示されるでしょう。

root@af8bae53bdd3:/#

コンテナ内でいくつかのコマンドを実行しましょう:

root@af8bae53bdd3:/# pwd
/
root@af8bae53bdd3:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var

pwd を実行すると、現在のディレクトリが表示されます。ここでは / ルートディレクトリにいることがわかります。また、ルートディレクトリ以下でディレクトリ一覧を表示すると、典型的な Linux ファイル・システムのように見えます。

これで、コンテナ内で遊ぶことができます。終わった後は exit コマンドか Ctrl-D を入力して終了できます。

root@af8bae53bdd3:/# exit

先ほど作成したコンテナと同様に、Bash シェルのプロセスが終了すると、コンテナは停止します。

Hello world のデーモン化

先ほどのように、コマンドを実行して終了するコンテナにも使い道はありますが、あまり有用ではありません。今度は、通常実行するであろう多くのアプリケーションと同様に、デーモンとして実行するコンテナを Docker で作りましょう。

次のように、再度 docker run コマンドを実行します:

$ docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147

あれ? ちょっと待ってください。 「hello world」の出力はどこに行ったのでしょうか。まずは、今ここで何を処理したのか確認しましょう。大部分が先ほどと同じコマンドに見えます。しかし docker run を実行するとき、今回は -d フラグを指定しました。-d フラグとは、コンテナ実行時にデーモン化し、バックグラウンドで動作するように Docker に対して指示します。

また、同じイメージ ubuntu を指定しました。

最後に、実行するコマンドを指定します:

/bin/sh -c "while true; do echo hello world; sleep 1; done"

これは世界で最も単純な (hello world) デーモンです。永遠に hello world を表示し続けるシェルスクリプトです。

それなのに hello world が表示されないのは何故でしょうか。そのかわり、Docker は長い文字列を返しました。

1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147

この長い文字列を コンテナ ID (container ID) と呼びます。個々のコンテナを識別して操作するのに使います。

注釈

コンテナ ID は長くて扱いにくいものです。もう少し後で、より短い ID をお見せします。こちらを使えば、コンテナをより簡単に操作できます。

このコンテナ ID を使い、hello world デーモンで何が起こっているのかを調べます。

はじめに、コンテナが実行中であることを確認しましょう。確認には docker ps コマンドを実行します。docker ps コマンドは、Docker デーモンに対し、デーモンが知っている全てのコンテナ情報を問い合わせます。

$ docker ps
CONTAINER ID  IMAGE         COMMAND               CREATED        STATUS       PORTS NAMES
1e5535038e28  ubuntu:14.04  /bin/sh -c 'while tr  2 minutes ago  Up 1 minute        insane_babbage

ここではデーモン化されたコンテナが見えています。docker ps は、コンテナ ID: 1e5535038e28 で始まる短いバージョンのコンテナ ID のほかにも、コンテナに関する便利な情報を返します。

また、構築時に用いたイメージは ubuntu であり、実行中のコマンドと、その状態、さらに自動的に割り当てられた名前が insane_babbage だと分かります。

注釈

Docker はコンテナ開始する時、自動的に名前を作成します。自分自身で名前を指定する方法は、後ほど紹介します。

大丈夫ですね。コンテナは実行中だと分かりました。しかし、実行時に指定した処理が正しく行われているでしょうか。コンテナの中でどのような処理が行われているか確認するには、docker logs を使います。Docker が割り当てたコンテナ名を使いましょう。

$ docker logs insane_babbage
hello world
hello world
hello world
. . .

docker logs コマンドは、コンテナの中をみて、その標準出力を返します。この例ではコマンド hello world の出力にあたります。

できましたね! デーモンは動作中です。始めて Docker 化したアプリケーションを作りました!

このように自分自身でコンテナを作れることを確認できました。あとは自分で後片付けのため、実行中のコンテナを停止します。停止するには docker stop コマンドを使います。

$ docker stop insane_babbage
insane_babbage

docker stop コマンドは、Docker に対して丁寧にコンテナを停止するよう命令します。処理が成功すると、停止したコンテナ名を表示します。

docker ps コマンドを実行して、動作確認しましょう。

$ docker ps
CONTAINER ID  IMAGE         COMMAND               CREATED        STATUS       PORTS NAMES

素晴らしいです。コンテナが停止しました。

次のステップ

ここまでは docker run コマンドを使い、初めてのコンテナを起動しました。フォアグラウンドで動作する双方向に操作可能なコンテナを実行しました。また、バックグラウンドで動作するデタッチド・コンテナも実行しました。この過程で、複数の Docker コマンドを学びました。

  • docker ps - コンテナの一覧を表示。
  • docker logs - コンテナの標準出力を表示。
  • docker stop - 実行中のコンテナを停止。

以上で、Docker の基本と高度な処理を学びました。次は シンプルなアプリケーションの実行 に移動し、Docker クライアントを使って実際のウェブアプリケーションを構築しましょう。