DockerをWindows Azure仮想マシンで使ってみた

最近噂のDockerを使ってみました。とりあえず大体分かってきたのでメモ。


# そもそもDockerとは
Docker(正確にはDocker Engine)とは、OSやHTTPなどのサーバー類をひとまとめにしたコンテナを作成することが出来るツール。たとえばHTTPサーバーとPHP・MySQLなどのサーバー環境をコンテナとしてイメージを作っておくことで、いつでもまったく同じ環境を作り上げて使うことができます。
そのため、開発中のサービス専用の仮想サーバーを作り、他の環境に影響を与えることなくカスタマイズしたり、いつでも同じ環境でサービスの試験を行うことができるという、便利なツールです。

## Dockerを使うには
DockerはLinux上のアプリですので、WindowsやMacでは利用できません。一応それぞれの環境用にVirtualPC上でDocker用環境を動かすBoot2Dockerという環境もあるそうですが、その説明はここでは行いません。

また、Dockerを利用するためのコンパクトなLinux、Core OSというものも存在します。今回は、Windows Azureの仮想マシンとしてCore OSを作成し、そのうえでDockerをいじってみました。

## OSのbin/bashに入る
とりあえず基本。

```
sudo docker run -i -t ubuntu /bin/bash
````

UbuntuのOSイメージをダウンロードし、シェルにログインします。試験的にパッケージをインストールしてみたり、後述するDockerfileで記載する処理をシミュレーションするときなど意外と使っています。

## Docker Hubのイメージを使う
Docker Engineは、[Docker Hub](https://hub.docker.com/)というサービスで公開さっれているOSイメージを取り込んで使うことができます。これを使ってごく普通のWordpressな環境やら、Ubuntuの環境やらを作成することもできます。

## Dockerfileを作ってOSイメージを作る
さてここからがDockerの本番。Dockerfileを作って独自のOSイメージを作ります。今回はとりあえずngixsのサーバーを作ってみます。

Core OSにSSHでログインし、~/に次のようなDockerfileを作成します。

```Dockerfile:Dockerfile
FROM ubuntu:trusty
MAINTAINER TakamiChiei<chie@onpu-tamago.net>

# パッケージのインストール
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get -y install nginx

# スタート
EXPOSE 80
CMD ["/usr/sbin/nginx", "-g", "daemon off;"]                                                                                                                
```

最後から二行目の`EXPOSE 80`が、ポートを公開する設定。これによってコンテナの外からコンテナないの80番ポート(つまり、HTTP)を表示することができるようになります。

かけたら早速実行。

```sh:ビルド
sudo docker build -t [タグ名] .
```

タグ名は、「自分の名前/任意の文字」と言うのが一般的なパターンのようです。自分の場合は、「takamichie/nginx」など

ビルドをすると、インストールするaptのインストール処理などでしばらく待たされます。一度ビルドした後、次にビルドするまでにパッケージが変更されてなかった場合は、ビルド処理が短縮されるようです(が、`apt-get -y install`でふたつ以上のパッケージをインストールするときは、短縮されない模様。面倒でもインストールは一行に一つだけとした方がいいのかもしれません)。

ビルドが終わったら、早速実行。

```sh:run
sudo docker run -p 8080:80 -d takamichie/nginx
```

これでnginxを起動したUbuntuのコンテナが実行され、HTTPが8080番ポートで公開されます(`-p 8080:80`は、「コンテナが80番ポートで公開している内容を、8080番ポートで外向けに公開する」という意味。ただし、WindowsAzure環境上ではもう一手間あります)。

### 8080番ポートをエンドポイントとして設定する

Windows Azure上でDockerを実行している場合は、Windows Azure仮想マシン内で公開されているポートを、仮想マシンのエンドポイントとして設定する必要があります。
「参照＞仮想マシン＞[仮想マシンの名称]＞Settings＞エンドポイント」より「追加」をクリックし、名前(エンドポイント)が「HTTP」、パブリックポート・プライベートポートを8080に設定したエンドポイントを作成します。
![2015-02-10_01h07_04.png](https://qiita-image-store.s3.amazonaws.com/0/14499/29ca8822-35ba-b767-ae5e-02b2aa48297f.png)

ここまでできたら早速仮想マシンのアドレス「[仮想マシン名].cloudapp.net」にアクセスしてみましょう。
![2015-02-10_01h18_56.png](https://qiita-image-store.s3.amazonaws.com/0/14499/1866d3be-0e28-82bc-65a4-1327fae23daa.png)
無事にサイトが表示されました。

## サイトをSSLに対応させる
さてそれでは、このサイトをSSLに対応させてみます。SSL証明書の発行には今回StartSSLを使用します。StartSSLの使い方は以下を参照してください。
-[無料のSSL証明書StartSSLを活用する](http://qiita.com/k-shogo/items/870b6d3939dd08da2de4)

ここから先の処理は、残念ながらAzureに最初から設定されているcloudapp.netドメインでは実行できません。独自のドメインを設定しておく必要があります。

ドメインが一個手元にある場合のみの記述になります。

### ドメインを設定する

まずはドメインを設定します。それぞれのドメイン管理画面にて、「[サブドメイン名].[ドメイン名]」のAレコードを作成します。
Aレコードの値は、Azureポータルの仮想マシンの情報ページにある「Virtual IP address」で大丈夫みたいです。

### 前準備
Azure仮想マシン上に、次の三つのファイルを作成します。

 * nginx用のSSL設定定義ファイル(ssl.conf)
 * 認証用ファイル(ssl.crt)
 * 認証鍵ファイル(ssl.key)

ssl.confの中身は、次の通り

```ssl.conf
server{
  listen 443;
  server_name devbael.onpu-tamago.net;
  ssl on;
  ssl_prefer_server_ciphers on;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers HIGH:!ADH:!MD5;
  ssl_certificate /etc/nginx/ssl_certfile/ssl.crt;
  ssl_certificate_key /etc/nginx/ssl_certfile/ssl.key;
}
```

とりあえず三つのファイルをCoreOSの~/に配置します。

### DockerfileにSSL関連処理を追加する

DockerfileにHTTPSに関連する処理を追加します。最近のnginxは初期設定で/etc/nginx/conf.d/というディレクトリに追加設定を置けるようになっているので、それを利用します。

```Dockerfile:Dockerfile(追加分のみ)
# SSL情報を格納
ADD ssl.conf /etc/nginx/conf.d/ssl.conf
RUN mkdir /etc/nginx/ssl_certfile/
ADD ssl.key /etc/nginx/ssl_certfile/ssl.key
ADD ssl.crt /etc/nginx/ssl_certfile/ssl.crt
RUN chmod 400 /etc/nginx/ssl_certfile/ssl.key
RUN chmod 400 /etc/nginx/ssl_certfile/ssl.crt
```

### 実行する

おわったら早速、build＆run。今回HTTPSは8081番ポートに結びつけておきます。

```sh:build＆run
sudo docker build -t [タグ名] .
sudo docker run -p 8080:80 -p 8081:443 -d takamichie/nginx
```

Azureのポータルより、8081ポートをエンドポイントに設定することをお忘れなく。

DNSの浸透後、設定したドメインを表示してみます。

![2015-02-10_01h42_09.png](https://qiita-image-store.s3.amazonaws.com/0/14499/10659adc-ea60-2b19-9b42-b9421c19950a.png)
無事表示されました。

# 今後
今後はひとまず、実際にサービスをデプロイしてためしてみたいと思います。
ひとまず公開できそうなネタができたら、また掲載したいと思います。