Rails, Django, Laravel 開発サーバをダブルクリックで起動する vagrant-layout プラグインというのを作った

vagrant-layout というのを作りました。

この記事で書いていた環境を生成する Vagrant プラグイン&設定サンプル集です。

layout

インストール

$ vagrant plugin install vagrant-layout

プラグインをインストールします。

Quickstart

$ mkdir my-project
$ cd my-project
$ vagrant layout init php

で各種ファイルを生成します。生成された、

  • sandbox/osx/start.command (Mac)
  • sandbox/win/start.bat (Windows)

をダブルクリックしてしばらく待つと、CentOS

が入った VMhttp://localhost:8080/ で起動します。

開発は手元のファイルを編集することで行います。ローカルのフォルダが /vagrant にマウントされており、 VM に即反映されます。

開発プロジェクトが一段落したら、

  • sandbox/osx/manage/uninstall.command (Mac)
  • sandbox/win/manage/uninstall.bat (Windows)

で環境をアンインストールできます。

vagrant layout init の後ろは vagrant-layout リポジトリのブランチ名です。

を指定できます。

Gist からインストールする

Rails

$ mkdir my-project
$ cd my-project
$ vagrant layout init https://gist.github.com/koseki/37f61d9a02b9a48e6651

で生成された start.{command|bat} をダブルクリックしてしばらく待つと、 http://localhost:8080/Rails が起動します。

Rails

Django

$ mkdir my-project
$ cd my-project
$ vagrant layout init https://gist.github.com/koseki/b7670fc1576a3129e4f7

で生成された start.{command|bat} をダブルクリックしてしばらく待つと、 http://localhost:8080/Django が起動します。

Django

Laravel

$ mkdir my-project
$ cd my-project
$ vagrant layout init https://gist.github.com/koseki/efbd631472c932ff2153

で生成された start.{command|bat} をダブルクリックしてしばらく待つと、 http://localhost:8080/Laravel が起動します。

Laravel

Gist の中身

Gist は、

  • ベースになるコミットの URL が書かれた README.md
  • パッチファイル patch

でできています。

vagrant-layout プラグインは、Gist に書かれたコミットをダウンロードし、git apply でパッチをあてます。(実行には Git が必要になります)

Gist の作り方はこの記事の最後で説明します。

ファイル構成

プロジェクトのルートディレクトリに sandbox を作成し、そこに開発環境用の全設定をいれます。

.
├── sandbox/
│   ├── Procfile
│   ├── Vagrantfile
│   ├── bin/
│   │   ├── boot.sh               …… サーバ起動スクリプト本体
│   │   ├── nginx.sh              …… Nginx 起動スクリプト
│   │   ├── provision.sh          …… プロビジョニング
│   │   ├── shoreman              …… foreman の shell 版
│   │   └── start.sh              …… サーバ起動スクリプト boot.sh を呼ぶだけ
│   ├── config/
│   │   ├── mime.types            …… Ngixn MIME-Type 設定
│   │   └── nginx.conf.src        …… Nginx 設定
│   ├── logs/                     …… ログディレクトリ
│   ├── osx/                      …… OSX 用スクリプト
│   │   ├── manage/
│   │   │   ├── init              …… 設定
│   │   │   ├── provision.command …… プロビジョニング実行
│   │   │   ├── ssh.command       …… SSH ログイン
│   │   │   ├── status.command    …… VM ステータス確認
│   │   │   ├── uninstall.command …… アンインストール
│   │   │   ├── up.command        …… VM 起動のみ実行
│   │   │   └── use-proxy.command …… プロキシ使用開始
│   │   ├── start.command         …… 起動
│   │   └── stop.command          …… 終了
│   └── win/                      …… Windows 用スクリプト
│       ├── manage/               …… OSX と同様なので省略
│       ├── start.bat             …… 起動
│       └── stop.bat              …… 終了
└── static/
    └── htdocs/
        └── index.html            …… ドキュメントルートサンプル

sandbox は開発環境専用のディレクトリです。プロジェクトは sandbox を消しても動くようにします。

sandbox とステージング・本番環境の設定について

ステージング・本番環境の設定と、ローカル開発環境の設定は分けるようにしています。認証、外部サービスとの連携、デバッグログ、SSL、ロードバランサや CDN などなど、多くの場合、環境に差がありすぎるので。

プロジェクトのルートディレクトリに config のようなディレクトリを作って、そこにステージング・本番用の Chef レシピを入れたりしています。

開発環境では開発者の作業しやすさを優先し、ステージング・本番はコストが許す限り同じ構成にします。

プロビジョニング

サーバ設定を変えたときは、チームメンバーに

  • sandbox/osx/provision.command (Mac)
  • sandbox/win/provision.bat (Windows)

をダブルクリックしてもらうように依頼します。このスクリプトは、vagrant provision を実行します。

Vagrantfile でプロビジョニングに sandbox/bin/provisioning.sh を使うように設定されており、これは、VM 上のファイル /root/.provisioning_version に書かれたバージョンよりも新しい処理を実行します。

VERSION=`expr $VERSION + 1`
if [ $CURRENT_VERSION -lt $VERSION ]; then
  echo "--- $VERSION: nginx ---"

  yum install -y -v nginx --enablerepo=epel

  # To stop 'could not open error log file' alert when starting nginx.
  chmod 777 /var/log/nginx

  echo $VERSION > $VERSION_FILE
fi

provisioning.sh に、上記のような if ブロックを追加していくことで、追加の構成をメンバー全員の VM に導入します。

シェルスクリプトを使ったプロビジョニングは冪等とは言えませんが、開発環境用としては、大概これで十分なのではと思います。プロビジョニングのために RubyPython が必須になると、導入のハードルが上がってしまいます。

開発メンバー向け環境構築手順

以下は開発メンバー (特に非エンジニア) 向けのセットアップ手順です。sandbox 入りのプロジェクトリポジトリを手元に clone してある前提です。開発メンバーが vagrant-layout プラグインを入れる必要はありません。

Windows の日本語ユーザディレクトリの問題

Windows を普通にセットアップすると、日本語のホームディレクトリができてしまいます。

Vagrant は日本語のホームディレクトリでは動きません。また ASCII でも特殊な文字が文字がパスに入っていると動きません。以下の issue を参照してください。

以下の手順で問題を回避します。

  • VAGRANT_HOMEC:\vagrant に設定する
    • start.bat から呼ばれる init.bat が設定するので気にする必要はありません。ディスク容量が足りなくなった時などに思い出してください
  • プロジェクトは C:\projects\my-project-name など、安全なパスに clone する
  • VirtualBoxmachinefolderC:\vms など、安全なパスに変更する

最後のは、VirtualBox のインストール後、VirtualBox マネージャを起動して、設定 > 一般デフォルトの仮想マシンフォルダー を書き換えます。

vbox

この設定は VirtualBox 上の全 VM で共通ですが、既にインストール済みの VM があっても特に影響しない(はず)です。古い VM は、そのまま同じディレクトリを参照し続けます。参考まで、最新の VirtualBox がどこに何を保存するかについてのメモが以下にあります。

Vagrant / VirtualBox / Git のインストール

Mac

Macインストーラを実行するだけです。何か聞かれたらデフォルトのままにします。

Windows

Windows は上の2つに加えて、Git をインストールしてください。Git パッケージに含まれる ssh.exe が必要です。

Windows で Git を通常と異なるパスにインストールしたい場合は (おすすめしませんが)、init.bat を修正するとかしてください。

Windows の Git はコンテキストメニューに大量の項目を追加します。普通いらないと思うので、

こちらの記事を参考に削除してください。

Windows の改行コード設定

VM にマウントされたシェルスクリプトを実行するには、改行コードに LF を使う必要があります。

全ファイルがコミットされた状態でsandbox/win/convert-eol.bat をダブルクリックします。

このスクリプトは、

git config core.eol lf
git config core.autocrlf input

を設定し、作業ディレクトリをリセットします。

git rm --cached -r .
git reset --hard

ちなみに、*.bat は CRLF でないと動きません。.gitattributes で改行コードを設定しています。

*.bat text eol=crlf

start.command で起動する

上記が終わったら、

  • sandbox/osx/start.command (Mac)
  • sandbox/win/start.bat (Windows)

VM を起動します。成功すると、

にアクセスできます。途中、

default: Warning: Connection timeout. Retrying...

みたいな表示が出ますが、これで正常です。VM が起動し終わるまで待っている状態です。この後、プロビジョニングと呼ばれるセットアップ処理が実行されます。

プロビジョニング開始前に止まってしまう場合

    default: Warning: Connection timeout. Retrying...
    default: Warning: Connection timeout. Retrying...
    default: Warning: Connection timeout. Retrying...
Timed out while waiting for the machine to boot. This means that
Vagrant was unable to communicate with the guest machine within
the configured ("config.vm.boot_timeout" value) time period.

のように止まってしまう場合は、VM が起動していません。以下をお試し下さい。

1. 一度アンインストールしてもう一回実行してみる

sanbox/osx/manage/uninstall.command または uninstall.bat でアンインストールしてから start.command を実行してみてください。

2. DHCP のバグ対応を試す

VirtualBox の初期設定が原因で、VagrantDHCP 設定がうまく動かない問題がありました。(最新版は自動で修正するようです)

この問題を回避するには、以下の手順を試します。

  1. VirtualBox マネージャーで、全仮想環境の電源が切れているのを確認。
  2. ターミナルから次のコマンドを実行し、表示される内容をどこかにメモする。(念のため)
$ VBoxManage list hostonlyifs
$ VBoxManage list dhcpservers
  1. ターミナルから次のコマンドを実行。
$ VBoxManage dhcpserver remove --netname HostInterfaceNetworking-vboxnet0

3. GUI で OS が起動しているか確認する

Vagrantfile を開いて、vb.gui = trueコメントアウトを外すと、GUI ウィンドウが開くようになります。 これで OS が起動していない場合は、何か根本的に問題があります。VagrantVirtualBox が正常にインストールできているかどうかを確認してください。

4. プロキシ設定が必要な場合

プロキシを設定しないと LAN から外に出られない場合。

Macsandbox/osx/manage/use-proxy.command をダブルクリックで実行してください。プロキシ設定ファイルのサンプルが sandbox/config/vagrant_proxy.conf に生成されます。

export http_proxy="http://user@passwd:www.example.com:8080"
export https_proxy="http://user@passwd:www.example.com:8080"
export no_proxy="localhost,127.0.0.1"

Windows は、use-proxy.bat を実行すると sandbox/config/vagrant_proxy.bat に同様のファイルが生成されます。

生成された vagrant_proxy.{conf|bat} をエディタで開き、各行を編集してください。

  • http_proxy …… HTTP 用プロキシ設定
  • https_proxy …… HTTPS 用プロキシ設定
  • no_proxy …… プロキシを使用しないドメイン

編集後、Mac は、最初に実行した use-proxy.command を再度ダブルクリックで実行します。設定がうまくいっていれば、プロキシ経由で vagrant-proxyconf プラグインがインストールされます。

Windows は、最初のウィンドウで何かキーを押すと、プラグインのインストールを開始します。ウィンドウを閉じた場合は、もう一度 use-proxy.bat をダブルクリックしてください。

プラグインのインストールが終わったら、 start.{command|bat} でセットアップを開始します。VM に自動的に

  • http_proxy
  • https_proxy
  • no_proxy

環境変数が設定されます。また、/etc/yum.conf 等にプロキシ設定が書き込まれます。

5. DHCP ではなく固定 IP を使いたい場合

sandbox/config/vagrant_ip.conf ファイルを作成し、1行目に

192.168.33.10

のように IP を書いてください。デフォルトでは DHCP を使います。

通常は DHCP がおすすめです。同じネットワーク内で複数のメンバーが作業する場合に面倒なことになります。

プロビジョニングが途中で止まってしまう場合

--- 1: nginx --- のようなインストール処理中に止まってしまった場合は、以下を試します。

  1. 一度 stop.command または stop.batVM を止める
  2. manage/provision.{command|bat} をダブルクリックで実行
  3. 無事終了したら start.{command|bat} をダブルクリックで実行

レイアウトのカスタマイズ方法

vagrant-layout リポジトリCentOS や Nginx、MySQL を固定で使っています。

設定を変えるには、 vagrant layout init コマンド実行後に、生成したファイルを編集すれば良いのですが、変更した環境を再利用したり共有したい場合もあるかもしれません。(あればいいなと思っています)

独自のレイアウトを共有するには、Gist を使う方法とリポジトリを fork する方法があります。

Gist を使う方法

ちょっとした変更であれば Gist を使うのが手軽です。

1. patch を作る

以下の手順で patch ファイルを作成します。

  1. vagrant-layout リポジトリを clone する
  2. ベースになるブランチをチェックアウトして、新しいブランチを作る
  3. 好きなだけ編集してコミット
  4. ベースになるコミットとの diffpatch ファイルに書き出す

例えば、Rails だと以下のような手順になります。

$ git clone https://github.com/koseki/vagrant-layout.git
$ cd vagrant-layout
$ git checkout ruby
$ git checkout -b rails

: ファイルを編集

$ git add -A .
$ git commit -m 'Rails 用レイアウト'
$ git diff 'HEAD^' > ../patch

更にコミットを加える場合は、'HEAD^' が正しいコミットを指すように調整してください。git commit --amend するなどして、ベースからの変更を1つのコミットにまとめておくのも良いと思います。

ベースコミットを変更したい時は、リポジトリから pull したあと変更分のコミットを rebase してください。

2. README.md を作る

README.md の末尾に、

---
base: ${ベースとなるコミットのURL}

を書きます。patch を生成するときに指定した比較元のコミットの URL を base に指定します。この URL をダウンロードしてパッチをあてます。

README.md は、サンプルの Gist をコピーするか fork してください。

パッチのベースになるのは特定のコミットなので、元のブランチが更新されたせいでパッチに失敗したり、動作が変わってしまうようなことはありません。

3. Gist に登録して確認

README.mdpatch を Gist に登録して、

$ vagrant layout init ${Gist の URL}

でうまく動くか確認します。

vagrant-layout リポジトリを fork する方法

大きな修正を行いたい場合や、URL ではなく名前で init できるようにしたい場合は、vagrant-layout リポジトリをフォークしてください。(どうぞお気軽に)

フォークしたレイアウトは、

$ vagrant layout init ${ユーザ名}/${ブランチ名}
$ vagrant layout init ${ユーザ名}/${リポジトリ名}/${ブランチ名}

でインストールできます。例えば、

$ vagrant layout init koseki/python

のようにします。また、特定のコミットを URL で指定できます。

$ vagrant layout init https://github.com/koseki/vagrant-layout/commit/80c34e5

といった具合です。確実に同じバージョンを使いたい場合などに、こちらをご利用ください。