【小ネタ】GitHubプライベートリポジトリにあるRailsアプリをProvisionするVagrantfile

2016.02.07

丹内です。掲題のとおり、プライベートリポジトリにあるRailsアプリを扱うVagrantfileを書きました。

背景

パブリックアクセスが設定されるリポジトリを元にしたProvisioningに比べて、実務上多いと思われるプライベートなリポジトリを扱うProvisioningに関する情報があまり無いようので、自分がやったことをまとめてみました。
Dockerはハードルが高いとしても、Vagrantなら手軽で敷居が低く、既存プロジェクトをポータブルする現実的な手法なのではないかと思います。

前提

  • Vagrant 1.8.1
  • VirtualBox 5.0.12
  • Mac OSX 10.11.3
  • sshを使ったプライベートリポジトリへのアクセス

Vagrantfile

agent forwardingして以下のVagrantfileでvagrant upするだけです。

Vagrant.configure(2) do |config|
  config.vm.box = 'puppetlabs/centos-7.2-64-nocm'
  config.ssh.forward_agent = true
  config.vm.network :forwarded_port, guest: 3000, host: 3000
  config.vm.synced_folder '.', '/vagrant', disabled: true

  config.vm.provision :shell, inline: <<-SHELL
    yum update -y
    yum install -y epel-release
    yum install -y http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
    yum install -y git ImageMagick ImageMagick-devel gcc-c++ glibc-headers openssl-devel readline libyaml-devel readline-devel zlib zlib-devel mysql-community-server mysql-community-devel libffi-devel libxml2 libxslt libxml2-devel libxslt-devel nodejs kernel-devel
    systemctl stop firewalld
    systemctl disable firewalld
    systemctl enable mysqld.service
    systemctl start mysqld.service
    /usr/bin/mysqladmin -u root password ''
  SHELL

  config.vm.provision :shell, privileged: false, inline: <<-SHELL
    ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock
    sudo echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> /home/vagrant/.ssh/config
    sudo chmod 600 /home/vagrant/.ssh/config
    git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
    git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
    echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
    echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
    ~/.rbenv/bin/rbenv install 2.3.0
    ~/.rbenv/bin/rbenv global 2.3.0
    ~/.rbenv/bin/rbenv exec gem i bundler
    git clone git@github.com:<Account Name>/<Private Repo Name>.git
    cd ~/<Private Repo Name> && ~/.rbenv/bin/rbenv exec bundle install --path vendor/bundle && ~/.rbenv/bin/rbenv exec bundle exec rake db:create db:migrate db:seed
  SHELL
end

補足

config.vm.box

今回はpuppetlabs/centos-7.2-64-nocmというBoxからスタートしています。Docker Imageもそうですが、ベースとなるイメージは極力公式の(身元が明らかな)ものを使いたいと考えています。
まず公式のCentOS7イメージが見つかるのですが、このBoxにはGuest Additionsが入っていないようです。
このコメントによるとpuppet labsのイメージだと入っているようなので、こちらを使いました。

config.ssh.forward_agent

trueを設定すると、vagrant ssh-configForwardAgent yesを設定してくれるので、ssh -Aしなくても良くなります。

config.vm.network

forwarded_portを設定する場合とprivate_networでIPを設定する場合があると思います。
今回は

  • Railsアプリ(標準で3000番で動作)は2つ以上動かさないので、ポートの重複はない(あってもログでわかる)
  • Dockerコンテナや他の仮想マシンでIPアドレスが重複するほうが面倒(Vagrantfileでハードコードすると他環境では動かないかもしれない)

ということで、forwarded_portを設定しました。

config.vm.synced_folder

==> default: Mounting shared folders...の部分で止まってしまい、仮想マシンは起動するけど遅いしエラーが表示されてびっくりすることがありました。
解決しても良いのですが、synced folderを使う予定もないので、無効にしました。

Agent Forwarding

利便性とセキュリティ上の観点から、仮想マシン内に鍵を生成・配置するのではなく、Agent ForwardingでホストのMacの秘密鍵を使ってプロビジョニングしています。
vagrant upの前に、以下のようにagentを準備しておきます。

$ ssh-add -K ~/.ssh/github-private
Enter passphrase for /Users/tannai.yuki/.ssh/github-private:
Passphrase updated in keychain: /Users/tannai.yuki/.ssh/github-private
Identity added: /Users/tannai.yuki/.ssh/github-private (/Users/tannai.yuki/.ssh/github-private)

$ ssh-add -l
1024 SHA256:ABCDEFGH /Users/tannai.yuki/.ssh/github-private (DSA)

$ ssh-agent

config.vm.provision

inline:にヒアドキュメントで渡したプロビジョニングが実行されます。
privileged: falseを設定しないとrootで、設定するとvagrantユーザでシェルスクリプトが実行されます。
ホームディレクトリや権限を意識して使い分けると良いです。

Rails起動時の注意

仮想マシン内でのRails起動時に、rails s -b 0.0.0.0とアドレスを明示しないと、ホストからフォワーディングできないので、注意が必要です。

Export時の注意

プロビジョニングしたBoxをvagrant packageでエクスポートするときに、仮想マシン内のDHCPのマッピングを消しておかないと不具合になるそうです(参考URL)。

まとめ

何かしらの方法で開発環境を仮想化してポータブルにしておくと、応援や引き継ぎの際に非常に便利なので、ぜひ設定しましょう。 今から始まるプロジェクトならDockerを使ったほうが良いかもしれませんが、それ以外のプロジェクトではVagrantを使ってBoxを作成する方法が低コストで良いです。