分析環境について考える（その２：VirtualBox＋vagrantで仮想環境を構築）

# 前置き
- [ 分析環境について考える（その１：全体像） ※2017年1月時点](http://qiita.com/9en/items/28e178c919bf38fcbc4f) の続き

# 分析環境構築の流れ
- 以下流れで仮想環境を構築していく

| No. | 内容 |
|:---------:|:---------|
| 1 | [全体像](http://qiita.com/9en/items/28e178c919bf38fcbc4f) |
| 2 | [VirtualBox＋vagrantで仮想環境を構築](http://qiita.com/9en/items/82e52ca87a0eaa2aa270) |
| 3 | [pyenv＋Anaconda[Python、R]＋jupyter＋Rstudioのインストール](http://qiita.com/9en/items/981a4bed401065c63168) |
| 4 | [postgreSQL+Pgadmin4のインストール](http://qiita.com/9en/items/43d2306f7e7e968b72c4) |

# 環境
- ホストOS：Windows7(64bit)
- ゲストOS：Ubuntu14.04(64bit)

# ソフトウェアのダウンロード
- [VirtualBox-5.1.10](https://www.virtualbox.org/wiki/Downloads)
- [vagrant_1.9.1](https://www.vagrantup.com/)

# Vagrantを用いてゲストOSをインストール
## Vagrantのバージョンを確認
```bash:コマンドプロンプト
> vagrant -v
Vagrant 1.9.1
```

## boxファイルを取得
- [boxファイル配布サイト](http://www.vagrantbox.es/)から選択
     - 「64bit」「No Guest Additions」のものを選択
     - 「Official Ubuntu 14.04 daily Cloud Image amd64 (Developmentrelease, No Guest Additions)」を選択
     -  後で必要なものをインストールするため最初は最低限のもののみ
- ダウンロード時間は数10分かかる
- boxファイルの保存先はデフォルトだと「C:\Users\hoge\.vagrant.d\boxes」配下に保存される
- 64bitのPCで、64bitのboxインストールできない場合の対処方法
⇒ BIOS設定画面で「仮想化支援機能」をオンにする（Intel(R) Virtualization Technology: Enabled）

```bash:コマンドプロンプト
> vagrant box add Ubuntu14.04 https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box
```

## 取得したboxファイルを確認
```bash:コマンドプロンプト
> vagrant box list
Ubuntu14.04 (virtualbox, 0)
```

## 仮想マシン用のディレクトリを作成
- ホームディレクトリ直下で作業してもよいが管理しやすいように仮想マシン用のディレクトリを作成する

```bash:コマンドプロンプト
> mkdir C:\Users\hoge\Documents\VirtualBox\vagrant
> mkdir C:\Users\hoge\Documents\VirtualBox\vagrant\Ubuntu14.04
> cd C:\Users\hoge\Documents\VirtualBox\vagrant\Ubuntu14.04
```

## Vagrantの初期化
- 指定したbox内の設定ファイル[Vagrantfile]をカレントディレクトリへコピーする

```bash:コマンドプロンプト
> vagrant init Ubuntu14.04
```

## Vagrantfileを編集
- Vagrantfileとは仮想マシンの構成を記述したファイル
- 「vagrant up」を実行するとvagrantfileに従って実行される
- プロビジョニングが記載された[provision_****.sh]は次回以降の記事にて記載する

```rb:Vagrantfile
Vagrant.configure("2") do |config|
  # box名
  config.vm.box = "Ubuntu14.04"
  # IPアドレスの設定
  config.vm.network "private_network", ip: "192.168.33.10"
  # ssh用のポート設定
  config.vm.network :forwarded_port, id: "ssh", guest: 22, host: 2222
  # jupyter用のポート設定
  config.vm.network :forwarded_port, id: "jupyter", guest: 22, host: 8888
  # Rstudio server用のポート設定
  config.vm.network :forwarded_port, id: "Rstudio", guest: 8787, host: 8787
  # プロビジョニングの設定を外部スクリプトから読み込む
  config.vm.provision :shell, :path => "provision_libs.sh"
  config.vm.provision :shell, :path => "provision_anaconda.sh", privileged: false
  config.vm.provision :shell, :path => "provision_rstudioserver.sh", privileged: false
  config.vm.provision :shell, :path => "provision_postgresql.sh", privileged: false
  # 共有フォルダの設定
  config.vm.synced_folder "./user", "/vagrant"
  config.vm.provider "virtualbox" do |vb|
    # メモリ割り当て
    vb.memory = "2048"
    # マシン名
    vb.name = "Ubuntu14.04"
  end
end
```

## プロビジョニングとは
- プロビジョニングとは設定やインストールを自動で実行すること
- プロビジョニングのツールとして以下のようなものがある
    - Chef
    - Puppet
    - Ansible
- しかしどれも学習コストが高そうだったため、今回はvagrant内でSHELLで記載する
- vagrantfile内でのプロビジョニングの[記載方法](https://www.vagrantup.com/docs/provisioning/shell.html)はいくつかあるが、今回は外部にスクリプトを書き出し、ファイル名を指定して読み込む

## 仮想マシンの起動
- Vagrantfileがあるディレクトリで実行する
- 初回の「Vagrant up」は自動でプロビジョニングが実行されるが、2回目以降はプロビジョニングが実行されないでマシンが起動するのみ(Vagrant 1.3.0以降)

```bash:コマンドプロンプト
> vagrant up
```

## その他Vagrantコマンド
- vagrantコマンドはvagrantfileがあるディレクトリで実行する

| 項目 | コマンド |
|:-------|:-------|
| 電源を強制的にオフ | vagrant halt |
| 仮想マシンの状態を調べる | vagrant status |
| 仮想マシンを完全に消去する | vagrant destroy |
| boxファイルを作成する | vagrant package --base <マシン名称> --output <output.box> |

## 仮想マシンへSSH接続
- WindowsのコマンドプロンプトからSSHはできないのでteratermなどのSSHクライアントを使ってログインする
- 接続ホスト(仮想環境用のIPを設定したため2種類で接続できる)

| ホスト | ポート |
|:-------|:-------|
| 127.0.0.1 | 2222 |
| 192.168.33.10 | 22 |

- アカウントは以下2種類が初期で用意されている

| アカウント | パスワード |
|:-------|:-------|
| vagrant | vagrant |
| root | vagrant |

# rootユーザの設定
- Ubuntuのデフォルトの設定ではrootユーザはパスワードが設定されていない
- 設定するには以下のようなコマンドを実行する

```bash:Ubuntu
# rootユーザに変更
$ sudo -s
password for ****: #ユーザのパスワードを入力

# rootユーザにパスワードを設定する
$ sudo passwd root 
[sudo] password for ****: # ユーザのパスワード
Enter new UNIX password: # rootパスワード設定
Retype new UNIX password: # 確認再入力
passwd: password updated successfully
```

# Vagrantを使ってウインドウ非表示でゲストOSを起動/停止させる
- 毎回コマンドプロンプトを起動させゲストOSを起動/停止させるのは面倒かつウィンドウが邪魔なため、ウインドウ非表示で起動/停止させる

```bat:up_Ubunt16.04.bat
@echo off
rem 起動
cd "C:\Users\hoge\Documents\VirtualBox\vagrant\Ubuntu14.04"
vagrant up
```
```bat:halt_Ubunt16.04.bat
@echo off
rem 停止
cd "C:\Users\hoge\Documents\VirtualBox\vagrant\Ubuntu14.04"
vagrant halt
```


# (参考まで)VirtualBoxを使ってGUIで仮想環境構築　※Vagrantを使わない方法

## VirtualBoxのインストール
- 以下記事を参考にインストール
    - https://gist.github.com/udzura/d368db4aff6d6adbe2e8

## TeratermからSSH接続
- ゲストOSから直接ターミナルを利用してもよいが、クライアントツールSSH接続を行う方が便利（ゲストOSは動きが遅い）
- 外部のクライアントツールからSSH接続するために以下を実施する
    - [ネットワークの設定](http://qiita.com/suneo3476/items/75112d0c62e857c19fcf)
    - VirtualBoxのターミナルから以下コマンドを実行する

```bash:Ubuntu
sudo apt-get install ssh
```
※コマンドを実行しないとTeratermのログイン画面で「OK」が押せない
※ネットの記事には「ONBOOT=yes」とするよう記載されているがこのコマンドで解決する

# VirtualBoxを使ってウインドウ非表示でゲストOSを起動させる
- 毎回VirtualBoxを起動させゲストOSを起動させるのは面倒かつウィンドウが邪魔なため、ウインドウ非表示で起動させる（消費メモリも削減できる）
- 方法として以下があるよう
    - コマンドラインから実行
    - VBScriptから実行
- わざわざVBScriptを利用する必要もないので、バッチファイルを作成し、ダブルクリックでゲストOSを起動できるようにする

```bat:Ubunt16.04.bat
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" startvm Ubunt16.04 --type headless
```
- コマンドラインから実行してもバックグラウンドで起動しているだけなので、通常のGUI上で起動しているのと同程度時間がかかる
- 進行状況を確認したい場合はVirtualBoxを起動するとプレビュー画面で確認できる（確認が終わればVirtualBoxを閉じて問題ない）

※ネット上では「VBoxHeadless」を利用した方法の記載が多いが、Widnsows環境で実行するとターミナルは立ち上がるものの途中で止まってしまう。「Ctrl+c」で強制終了すると仮想マシンが「中断状態」となる。


# 参考
- https://gist.github.com/udzura/d368db4aff6d6adbe2e8
- http://qiita.com/suneo3476/items/75112d0c62e857c19fcf
- http://webvox.jp/virtualbox-ubuntu-teraterm/
- https://www.server-world.info/query?os=Ubuntu_14.04&p=initial_conf&f=2