boot2dockerを利用してDocker上のnginxにアクセスしてみる

  • 42
    Like
  • 0
    Comment
More than 1 year has passed since last update.

Dockerを使い始めてみたので、覚え書き的に書いていきます。
おかしいところなどあればご指摘下さいm(_ _)m

今回のゴール

・Dockerの基本機能の把握+理解
・ローカル環境でnginxが動作するDockerコンテナを構築する。

Dockerとは

DockerはImmutable Infrastructureという概念を採用しており、どの環境にデプロイしても冪等性を担保したインフラを実現する技術である。
つまり、
・デプロイしたら動かなかった
・デプロイ先によってバージョンが異なる
といった問題が生じない

Dockerはコンテナと呼ばれるアプリケーションのパッケージを作成することでき、Dockerfileに設定を記述することで独自のコンテナを作成することができる。
もちろん予め用意されたイメージを利用することも可能で、dockerhubというサイト上に存在するイメージをpullしてきて利用ができる。
Dockerfile内に利用したいイメージを記述することで既存のイメージに設定の追加した独自のイメージを作成することも可能。

DockerはLinuxでしか利用できないためMacで利用するにはboot2docker経由でDockerを利用する必要がある。
http://boot2docker.io/

Virtualboxのインストール

boot2dockerはvirtualbox上で走るcoreosの仮想マシンなのでまずはVirtualboxをインストールする
https://www.virtualbox.org/wiki/Downloads

Dockerのインストール

brewでDocker/boot2dockerをインストール

brew install docker boot2docker

インストールされたことを確認

boot2docker version
docker -v

まずはdockerを動かすための仮想マシンであるboot2dockerを初期化→起動

boot2docker init
boot2docker up

upした時点でDOCKER_HOSTという環境変数を設定するように出力されるので、それに従って~/.zshrcや~/.bash_profileなどに適宜設定する。

CentOSイメージを取得

DockerHub上には多数の公式イメージも存在している
https://registry.hub.docker.com/

今回はそこからCentOSの公式イメージをインストールする。

docker pull centos

docker pullはイメージを取得してくるコマンド

docker images

docker imagesでcentosが表示され、pullされていることを確認する

早速動かしてみる

早速インストールしてきたイメージを動かしてみる。
↓のサンプルはcentosイメージに"hello docker"を出力させる例

docker run centos echo "hello docker"

また、以下のように標準入力を開く事も可能である

% docker run -i -t centos /bin/bash
bash-4.2# echo "hello docker"
hello docker
bash-4.2# exit
exit

イメージを保存する

さらに、イメージに対して変更を加えた場合(例えば、標準入力内でyum installなどを行った際など)、その変更適用済みのイメージを他の部分でも使いたい場面などがある。
Dockerにはcommitという変更を適用した状態をセーブする機能が存在し、commitすればその後、そのコミットした状態からイメージを操作することができる。
↓の例ではecho "hello world"を実行し、docker ps -aで実行済みのプロセスも含め表示させている。

% docker run centos echo "hello world"
hello world
Reo-no-MacBook-Pro% docker ps -a
CONTAINER ID        IMAGE              COMMAND                CREATED            STATUS                    PORTS                NAMES
43fa67c118f5        centos:centos7      echo 'hello world'    24 hours ago        Exited (0) 3 seconds ago                        mad_lumiere

するとそれぞれにCONTAINER_IDというユニークなIDが発行されるので、そのIDをcommitしていく

% docker commit 43fa67c118f5 centos:helloworld
de44ab74e61aa20156013946717c3f13937802b63e88378d5c8cac4b55ea9ae6

↑の例では43fa67c118f5というcontainer_idに対してcentos:helloworldというイメージを作成している
イメージの名前は「:」で区切られているが、手前がイメージ名、後ろがタグとなっている。
実際にイメージが作成出来ているかを確認するために、イメージの一覧を出力するdocker imagesを実行する

% docker images
REPOSITORY          TAG                IMAGE ID            CREATED            VIRTUAL SIZE
centos              helloworld          de44ab74e61a        24 hours ago        236.4 MB

実際にtagがhelloworldとなっているdockerイメージが生成されているのを確認できた。

Dockerイメージを作成する

Dockerfileを作成

これまでは既存のdockerイメージを利用していたが、実際に自分でイメージをビルドして使ってみる。
Dockerのイメージをビルドする際はDockerfileというファイルを作成し、その中に環境を記述してあげれば、思い通りのイメージを作成できる。
以下の例ではnginxをインストールし、実行する命令を記述している。

FROM centos

MAINTAINER reoy

RUN yum update -y

ADD nginx.repo /etc/yum.repos.d/
RUN yum install -y nginx

EXPOSE 80
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]

Dockerfileの説明としては
FROMは作成するイメージのもととなるイメージ。ここではcentosの環境を利用したいのでFROMにcentosを指定している。
MAINTAINERは作成者
RUNはビルド時に実行される命令を設定することができるコマンド
ADDはファイルをローカルからイメージの中にコピーするコマンド
EXPOSEはイメージがコンテナとして実行された際に開放するポートを指定するコマンド
ENTRYPOINTCMDというコマンドと似ているが両方共にビルド時ではなくdocker runのタイミングで実行されるコマンド。それぞれの違いは主にシェルを通してコマンドを実行しているかどうかである。
また、上記の例のnginx.repoは
http://wiki.nginx.org/Install
↑のサイトを参考に作成している

ビルドしてみる

ここまでで作成したDockerfileを基に実際にビルドしてみる

docker build -t centos/nginx:test .

↑ではビルドを実行しており、-tオプションをつけることでタグをつけている。つまり例ではcentos/nginxという名前のイメージを作成し、そのイメージにtestというタグをつけている。
末尾の「.」はカレントディレクトリを指しており、絶対パスでDockerfileのあるディレクトリを指定する事も可能。
docker imagesを実行して、先ほど作成したイメージが作成されていることを確認

% docker images
centos/nginx        test                775fd7e82bf1        37 hours ago        321.8 MB

RUNしてみる

それでは先ほど作成したイメージを実行してみる

% docker run -d -p 80:80 centos/nginx:test
6a9d9f667462d7d216f76f2a41753c0362221c4f85dc47e2f99b304bbc93e519
% docker ps
CONTAINER ID        IMAGE              COMMAND                CREATED            STATUS              PORTS                NAMES
6a9d9f667462        centos/nginx:test  /usr/sbin/nginx -g '  38 hours ago        Up 13 hours        0.0.0.0:80->80/tcp  lonely_ritchie

docker runコマンドに-pオプションを付けることでホストOSとdockerコンテナのポートを紐付ける事が可能となる。この場合はホストの80番ポートとコンテナ内の80番ポートの紐付けを行っている。
docker psで実際にnginxが実行されてことを確認できた。
それではcurlをローカルホストに投げてみる

curl http://localhost:80
curl: (7) Failed connect to localhost:80; Connection refused

refuseされたがこれは当然の事である。
先ほど-pオプションをつけてポートを80番に設定しているがそれは「仮想マシン(boot2docker)の80番ポートとdockerの80番ポート」を紐付けたに過ぎないため、OSX上のポートとは紐付いていない。
そこでVirtualboxのポートフォワーディング機能(GUI)を利用してOSXの8080番ポートと仮想マシンの80番ポートを紐付ける必要がある。
もちろん以下のVBoxManageコマンドを利用すればコマンドラインからVirtualBoxの仮想マシンのポートフォワーディングを実行できる。

VBoxManage controlvm "boot2docker-vm" natpf1 "nginx,tcp,127.0.0.1,8080,,80"

ポートフォワーディングを実行したうえでもう一度curlを実行し、値が返ってくることを確認

% curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

もちろんブラウザからもlocalhost:8080にアクセスで確認可能

次回予告

AWS Elastic Beanstalkを使って実際にrailsアプリをデプロイするところまでやってみようと思いますー。