EagleLand

2015.09.14

Docker事始め作業ログ

やってみよう系の記事は既にチラホラあるけど、手元の環境に合わせて書き直したただの作業ログ。

Dockerとは

ざっくりこのような感じだが、パッとこない場合は以下の記事が参考になる。

Mac OS XにDocker環境を準備する

以下のものをインストールする必要アリ。公式で配布されているDocker Toolboxでも良いが、インストーラ使うとroot領域いじられそうなので、VirtualBox以外はHomebrew経由でインストールする。boot2dockerは使わない。

$ brew install docker
$ brew install docker-machine

あとは公式のチュートリアルに沿ってDockerの振る舞いを理解していく。

Docker Machineで仮想マシンを作成する

Docker Machineで仮想マシンを立てる。VirtualBoxを使うので、--driverで指定し、マシン名も引数に取る(ここではlocalというマシン名を指定)。作成すると~/.docker/machine/machines/localというフォルダが作成され、マシンの各種設定が保存される。

$ docker-machine create --driver virtualbox local

Docker Machineで作成したマシンはlsコマンドでリストアップできる。マシンを削除するにはrmコマンドで。

$ docker-machine ls
NAME    ACTIVE   DRIVER       STATE     URL                         SWARM
local            virtualbox   Running   tcp://192.168.99.100:2376

$ docker-machine rm local

仮想マシンの各種環境変数

作成したマシンの各種環境変数はenvコマンドで取得可能。出力結果をevalするとそのまま変数を定義できる。

$ docker-machine env local
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/1000ch/.docker/machine/machines/local"
export DOCKER_MACHINE_NAME="local"
# Run this command to configure your shell:
# eval "$(docker-machine env local)"

hello-worldコンテナを実行してみる

先程のenvコマンドで得られる環境変数をexportした上で、いよいよDockerでコンテナを起動する。今回はhello-worldというコンテナを指定しているが、実行に成功するとハローワールドが表示される。

$ eval "$(docker-machine env local)"
$ docker run hello-world

ここではhello-worldというコンテナを指定しているが、以下の手順が実施されている。Docketクライアントはコマンドを叩いているターミナルということになる。

  1. DockerクライアントがDockerデーモンに問い合わせる
  2. Dockerデーモンがhello-worldイメージをDocker Hubからダウンロードする
  3. Docketデーモンがダウンロードしてきたイメージから新たにコンテナを作成する
  4. Dockerデーモンがコンテナを標準出力をDocketクライアントに流す

nginxコンテナを試してみる

バックグラウンドで実行させるために-d--detach=false)を、ランダムにポートを割り当てるために-P--publish-all=false)を、明示的に名前を付与すべく--nameも付けて実行する。nginxのプロセスは終了するまで実行され続けるので、-dを付けないとターミナルが持っていかれる。

$ docker run -d -P --name nginx-web nginx

起動中のコンテナ一覧の表示、コンテナの開始と停止と削除

停止にはstopコマンドを、削除にはrmコマンドを使う。それぞれコンテナのID指定するが、コンテナIDは先程のrunコマンドの-dオプションで出力される他、psコマンドの出力結果にも表示される。尚、コンテナに名前が指定されていればコンテナIDではなくコンテナ名を指定しても実行できる。

# 起動中のコンテナ一覧を表示する
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                           NAMES
ba377526b912        nginx               "nginx -g 'daemon off"   26 seconds ago      Up 2 seconds        0.0.0.0:32775->80/tcp, 0.0.0.0:32774->443/tcp   nginx-web

# 指定したコンテナを停止する
$ docker stop ba377526b912

# 指定したコンテナを開始する
$ docker start ba377526b912

# 指定したコンテナを削除する
$ docker rm ba377526b912

nginxがホストしているページをブラウザで表示する

portコマンドでコンテナに対してマッピングされているポート番号を一覧化できる。先程nginx-webという名前でコンテナを起動したので、それがどのポートに割り当てられているかを確認してみる。

$ docker port nginx-web
443/tcp -> 0.0.0.0:32774
80/tcp -> 0.0.0.0:32775

コンテナの443ポートがローカルホスト(Dockerクライアント)の32774に、コンテナの80ポートがローカルホスト32775にマッピングされているのがわかる。

マシンのIPアドレスを調べる

先程のコンテナのIPアドレスはDockerのホストアドレスではないので、nginxにはアクセスできない。Docker Machineで作成したマシンのIPアドレスをipコマンドを使って調べる。echo $DOCKER_HOSTあたりを実行すると、docker-machine envで出力されたDOCKER_HOSTのIPと一致しているのがわかる。

$ docker-machine ip local
192.168.99.100

$ echo $DOCKER_HOST
tcp://192.168.99.100:2376

ブラウザでnginxでホストしているページへアクセスする

ここまででnginxが192.168.99.100:32775を待ち構えていることがわかるので、 http://192.168.99.100:32775 にアクセスしてみる。

ローカルのディレクトリをコンテナにマウントする

次に、ローカルのディレクトリをコンテナにマウントしてみる。適当なディレクトリにindex.htmlを配置して、配置したディレクトリをnginxのホストディレクトリにマウントする。それが出来れば先程のURLでindex.htmlの内容が表示されるはずだ。今回はユーザーディレクトリ配下にfooというフォルダを用意し、その中にindex.htmlを配置した。HTMLの中身は何でも良い。

コンテナの再作成からやるので、docker psで起動しているコンテナのコンテナIDを取得し、docker stop [コンテナID]docker rm [コンテナID]で先程作成したコンテナ(nginx-web)を削除する。削除せずに違う名前でも良いんだけど、テストがてら。

$ docker ps
...

$ docker stop 4bf9cfc2fe49
$ docker rm 4bf9cfc2fe49

削除したら、以下のコマンドで再度nginxのコンテナを作成する。さっきと違うのは、-vオプションでマウントするディレクトリをしている点。ユーザーディレクトリ配下のfooフォルダをマウントするので$HOME/fooとし、マウント先にはnginxがホストするディレクトリである/usr/share/nginx/htmlを指定している。

$ docker run -d -P -v $HOME/foo:/usr/share/nginx/html --name nginx-web nginx

起動したら再びdocker port nginx-webで割り当てられたポート番号をチェックし、ブラウザでアクセスしてみる。用意したindex.htmlの中身が表示されればひと通り成功。

$ docker port nginx-web
443/tcp -> 0.0.0.0:32776
80/tcp -> 0.0.0.0:32777
# ブラウザで http://192.168.99.100:32777 にアクセスしてみる

まとめ