はじめに
現在Docker
に対して造詣を深めようとしているところで、まだまだわかってない状況です。
その中で少しわかってきたのが、Vagrant
とは違いDocker
はイメージベースでやり取りをするためにある気がしました。
すなわちDocker
は誰かが作ったスナップショットをもらって、その環境を使って仕事を行う事を目的をして使われる事が多いのではないかと思い始めました。
Vagrant
+Chef
の構成を容易にやり取りできる感じでしょうか?
Chef
のレシピで細かいところまで設定すると仰々しくなり、汎用的に使えなくなります。
一方でDocker
は元のイメージを複製して、イメージ内を変更して適した形にしたところでスナップショットを取って配布していくので汎用的に使えなくても問題がないという思想なのかなと思いました。
なので、今回は人が作ったイメージをMacで再現(再生?w)してみようと思います。
目標はDockerで即実行できる、社内・自宅向けオープンソースWebアプリを起動する事です。
前回まで行った事
前回行った事で重要なところだけピックアップします。
(前回の記事はメモ書きだったので、見てもわけがわからないと思うので・・・)
必要なモノをインストール
以下の二つを事前に入れておいてください。
もしdocker-machine
の設定済みだった場合飛ばしてください。
- VirtualBox
- HomeBrew
その状態で以下を入れます。
$ brew install docker docker-machine
これでDocker
のVMを管理するdocker-machine
とコマンドを管理するdocker
が入りました。
念のため確認します。
$ docker -v
Docker version 1.8.1, build d12ea79h
$ docker-machine -v
docker-machine version 0.4.1 (HEAD)
次はVMを入れます。
dev
はVMの名前なので、なんでも良さそうです。
$ docker-machine create --driver virtualbox dev
起動
入れたVMを起動します。
もしdocker-machine
の設定済みだった場合飛ばしてください。
$ docker-machine env dev
設定を追加します。
$ vi ~/.bash_profile
# 一番最後に設定
eval "$(docker-machine env dev)"
# 反映
$ soruce ~/.bash_profile
docker-machineの各種コマンド
IPアドレスの確認
$ docker-machine ip dev
192.168.99.100
VMの確認
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
dev * virtualbox Running tcp://192.168.99.100:2376
VMへログイン
$ docker-machine ssh dev
VMの起動/終了コマンド
# 起動
$ docker-machine start dev
# IPアドレスが変わるので、必要に応じて起動後に一度実行する。
$ docker-machine env dev
$ source ./bash_profile
# 終了
$ docker-machine stop dev
Dockerの各種コマンド
イメージ取得
$ docker pull ubuntu:latest
イメージ起動
$ docker run centos:latest echo "Hello World"
echo "Hello World"
はインストール後に行う命令。
イメージが無い場合は、ダウンロードして実行される。
$ docker run -it --name ubuntu1 ubuntu /bin/bash
取得したイメージを起動することができる。
主な[オプション]
- -d:バックグラウンドで実行する(後述)。既定では、コンテナーをフォアグラウンドで実行するため、Webサーバーやアプリケーションサーバーなど常時実行するコンテナーで指定
- -i:コンテナーの標準入力を開く。/bin/bashなどでコンテナーを操作する際に指定
- -t:tty(端末デバイス)を確保する。/bin/bashなどでコンテナーを操作する際に指定
- -p {ホストのポート番号}:{コンテナーのポート番号}:Dockerサーバーのホストとポートマッピングを構成
ついに1.0がリリース! Dockerのインストールと主なコマンドの使い方 (2/3)より引用。
イメージ確認
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos latest e9fa5d3a0d0e 7 weeks ago 172.3 MB
コンテナ確認
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
93d9d73dff28 ubuntu "/bin/bash" 3 minutes ago Exited (0) 5 seconds ago ubuntu1
38f47d2577f6 centos:latest "echo 'Hello World'" 3 hours ago Exited (0) 3 hours ago mad_poitras
NAMES
は指定しないと勝手につけられる。
今回の例ではmad_poitras
となってるので、以下のmad_poitras
の部分については適時読み替えてください。
-a
をつけない場合は起動しているコンテナだけを確認できる。
コンテナに入る。
$ docker attach mad_poitras
初めのコマンドは見えないので、その場合は以下のコマンドで入れば見れる。
(@hidekuroさんに教えてもらいました。)
$ docker logs CONTAINER_NAME && docker attach CONTAINER_NAME
一度入り込んで抜けるとコンテナは止まってる。
イメージの保存
Dockerを起動して中身を変更します。
$ docker start ubuntu1
$ docker attach ubuntu1
root@93d9d73dff28:/# apt-get install -y nginx
root@93d9d73dff28:/# dpkg -l nginx
root@93d9d73dff28:/# exit
変更内容をイメージに保存します。
$ docker commit ubuntu1 ubuntu/nginx
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu/nginx latest a3bbb2669586 7 seconds ago 206.1 MB
ubuntu latest e9ae3c220b23 3 weeks ago 187.9 MB
新しいイメージができてます。
出来なかったことのメモ
上記のイメージを80番ポートフォワードでnginxコンテナを起動。
$ docker run -d -p 80:80 --name nginx1 ubuntu/nginx /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
$ curl localhost:80
# curl: (52) Empty reply from serverが出る場合はVMのポートフォワーディングを変更してください。
注意
Macで上記を行う場合はこちらの設定が必要となる。
コンテナの停止
$ docker stop mad_poitras
コンテナ起動
$ docker start mad_poitras
コンテナの削除
$ docker rm mad_poitras
イメージの削除
イメージの削除はコンテナを全て削除しないと実施できない。
docker rmi e9fa5d3a0d0e
e9fa5d3a0d0e
はdocker images
のIMAGE ID
を指定する。
イメージ検索
$ docker search ubuntu
Dockerfileを使用
少し憂いがあるが、目標のために突き進む。
Dockerfile
を使用するとあらかじめ設定した通りにイメージを作成してくれる。
$ mkdir nginx
$ cd nginx
$ vi Dokerfile
適当なディレクトリにDockerfile
を以下のように作成する。
FROM ubuntu
RUN apt-get install -y nginx
ADD index.html /usr/share/nginx/html/
上記の例ではあらかじめindex.html
をnginxディレクトリ
に作っておく必要がある。
イメージを作成する
実際にここからイメージ
を作成する。
$ docker build -t ubuntu/nginx:10 .
ubuntu/nginx
という名前でTAGを10
で作成する。
最後の.
は現在のディレクトリを指している。
コンテナを起動する
以下のコマンドで先ほど作成したイメージのコンテナを起動する。
docker run -d -p 80:80 --name nginx1 ubuntu/nginx:10 /usr/sbin/nginx -g
ENTRYPOINTを使用する。
Dokerfile
を以下のように記載すると起動コマンドを省略することができる。
FROM ubuntu
RUN apt-get install -y nginx
ADD index.html /usr/share/nginx/html/
ENTRYPOINT /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
コンテナ起動まで行う。
$ docker build -t ubuntu/nginx:1.1 .
$ docker run -d --name nginx2 -p 62733:80 ubuntu/nginx:1.1
一つ目の目的を達成する。
Dockerで即実行できる、社内・自宅向けオープンソースWebアプリに記載されている一番最後のイメージはDockerfileで定義されているので、上記の知識を使いイメージを作ってみる。
$ mkdir reichat
$ cd reichat/
$ vi Dockerfile
ページに書かれている事をそのまま実装する。
FROM node:0.12.2
RUN npm install -g reichat
EXPOSE 10133
CMD reichat
イメージの作成をして実行
$ docker build -t reichat .
# WARNがいっぱい出るけど・・・
$ docker run -d --name reichat -p 10133:10133 reichat
この設定も忘れずに行う。
ブラウザでhttp://localhost:10133/
へアクセス!
やった!できた!!
$ curl localhost:10133
これでもデータの取得ができた!
感想
nginx
の場合はうまくポートフォワードが出来なかったが、reichat
はうまくできた。
・・・と言う事はnginx
の設定が何か悪かったのだろう。
→解決しました。コンテナ起動時の-p 62733:80
の設定は考えすぎで-p 80:80
で起動させて、VMのポートフォワーディングで対応すればOKでした。
分かるとあっという間にイメージを作れてWebサイトが生成されるので驚きだった。
そして、ページが見れた時はちょっと感動したw
確かにこれでイメージを受け渡せば開発環境のスナップショットの受け渡しや、一つのサーバー内でいくつものサーバーを内部で立てれるのはすごい魅力だ。
(自分のローカルに本番環境を立てる事もできるだろう・・・。)