vagrant up 一発で立ち上がるウェブアプリケーション開発環境作り　第三回：プロキシサーバー編

VagrantとDocker（とDocker Compose）を使って開発環境を一発で立ち上げられるようすることを目標とした連載、第二回です。
[第一回：Vagrant編](http://qiita.com/marrontan619/items/01cf11fa74af5bbdd96b)
[第二回：Docker編](http://qiita.com/marrontan619/items/6ed07ad391884bfa1a22)

## ホストマシンからHTTPで接続できるようにする

前回記事にしたdocker-compose.ymlのこの部分について、詳しく見ていきます。

```yaml:docker-compose.yml
version: "2"
services:
  # reverse-proxy
  proxy:
    image: nginx:latest
    volumes:
      - /vagrant/docker/proxy/volume/conf:/etc/nginx/conf.d:rw
      - /vagrant/docker/proxy/volume/log:/var/log/nginx:rw
    ports:
     - "80:80"
     - "443:443"
    #links: # 今回は関係なし
    #  - app:app
```

## Vagrantに固定IPをつける

docker-compose upを実行する前に、Vagrantfileに以下の内容を追記して、ホストのブラウザなどから固定IPで接続できるようにしてから、VMを作り直します。（destroyしなくても、haltで十分です）

```ruby:Vagrantfile（抜粋)
Vagrant.configure(2) do |config|
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.network "forwarded_port", guest: 80, host: 8080
end
```

* private_network:ホストとVagrantのVM間で接続するためのIP
* forwarded_port：外部（ホスト以外のマシン）からVMに接続したい場合に、<ホストのIP>:8080などで接続できるようにするための設定

まずはdocker-compose.ymlのあるディレクトリで

```
docker-compose up -d --build proxy
```

を実行したら、ホスト（Windowsなど）のブラウザから
http://192.168.33.10
でNginxのウェルカム画面が出ることが確認できるはずです。これは
ホストのブラウザ
↓
Vagrant（192.168.33.10）の80番ポート
↓
proxyコンテナの80番ポート

の順に接続しています。
この接続のためには

1. DockerfileでEXPOSEの設定し、ポートを公開する
2. docker runで-pの設定し、Vagrantからポートフォワーディングする

という手順が必要です。
EXPOSEはDocker Hubから取得したnginxのイメージが既に設定しているため、今回は不要。
Vagrantからコンテナへのポートフォワーディングは、docker-compose.ymlのports:の部分で設定しています。

本コンテナの最終的な役割はアプリケーションサーバーへのプロキシですが、まだそれは作成していないので、今回はおまけとしてNginxの設定などをしていきましょう。

## おまけ1：Nginxの設定

### 設定をカスタマイズする

Nginxは起動時に/etc/nginx/conf.d/*.confファイルを読み込みます。
コンテナ起動時に、そこにファイルが置かれているように、volumes:で設定します。
docker runの場合は-vオプションです。

```file:ディレクトリ構成（ホスト）
<vagrant-root>
├── docker
│   ├── docker-compose.yml
│   └── proxy
│       └── volume
│           ├── conf # コンテナの/etc/nginx/etc/conf.dに対応
│           │   └── httpd.conf
│           └── log # コンテナの/var/log/nginxに対応
│               ├── access.log
│               └── error.log
├── package.box
├── provision.sh #第一回参照
└── Vagrantfile
```

これでhttpd.confがproxyコンテナの/etc/nginx/etc/conf.dに配置され、設定が読み込まれるようになります。
（内容については、プロキシを設定する際に書きます。）

### ログをホストから見えるファイルに出力するようにする

Docker公式のNginxイメージの設定を見てみましょう。

```
# Vagrantからコンテナに入る
docker exec -it docker_proxy_1 bash
# Nginxの設定ファイルを確認
cat /etc/nginx/nginx.conf
```

内容はこうなっていました。（2017/04/02時点）

```nginx:nginx.conf
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
```

access.logとerror.logは/var/log/nginx/に出力されるようなので、これをホストから見えるようにdocker-compose.ymlのvolumes:で設定しています。

## おまけ2：ホスト（Windows）、ゲスト（Vagrant）、コンテナ間のIPについて

それぞれの取得方法について、調べた範囲で書いていきます。

### ホスト→Vagrant

config.vm.network "private_network", ip: "192.168.33.10"
Vagrantfileのここで設定したIPです。

### Vagrant→ホスト

10.0.2.2 固定…らしいです。（未確認）

```
netstat -rn | grep "^0.0.0.0 " | cut -d " " -f10
```

これで取得できます。

### Vagrant→コンテナ

docker inspectで調べます。
JSON形式で表示されるため、jqコマンドを入れるともっと綺麗になるのですが、手っ取り早く

```
docker inspect <コンテナ名> | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "",
                    "IPAddress": "172.18.0.4", ←これ
```

こんな感じで調べられます。

### コンテナ→コンテナのホスト（Vagrant）

```
/sbin/ip route|awk '/default/ { print $3 }'
```

で取得できます。

## 結び

プロキシサーバー編と題しておきながら、ただHTTPサーバー用のコンテナを立ち上げて繋ぐだけで終わってしまいました。
次回、[アプリケーションサーバー編](http://qiita.com/marrontan619/items/f2f2c796f4d039598101)に続く