タグ: Vagrant

vagrantのshell provisionerにrun: “always”オプションを使うことでvagrant upするたびにdocker-composeを実行させる

開発環境をVagrantDocker(docker-compose)で構築したのですが、毎回コンテナを起動するために

  1. vagrant up
  2. SSHでゲストOSにログイン
  3. ゲストOS上でdocker-compose up

という手順を踏んでいました。

VagrantとDockerを使ったPHP実行環境を生成するサービス:PHPDocker.io – PHP and Docker development environment generator で生成されるVagrantfileを見ると、以下の方法でdocker-composeを起動させていました。

    # Bring up containers
    config.vm.provision "shell", run: "always", inline: "cd /home/docker/sample/phpdocker && docker-compose up -d 1>&2"

runオプションはProvisionerの共通オプションで、デフォルトでは最初のvagrant upでのみprovisionerが実行されますが、alwaysを指定することで、vagrant up, vagrant reloadのたびに実行されるようになります。

実際には以下のようにして使っています。

冒頭の3.のdocker-compose upはserver.shというスクリプトに書いてserver.sh upとして使っていました。

#!/bin/bash -eu

PWD=$(cd $(dirname $0); pwd)
PROJNAME=sampleproject

ARGS=
if [ $# -eq 0 ];then
    ARGS="up -d"
else
    ARGS=$@
fi

cd $PWD && docker-compose -p $PROJNAME $ARGS

Vagrantfileに以下の内容を追加しました。

  config.vm.provision "shell", run: "always", inline: "[ -f /home/vagrant/sampleproject/server.sh ] && /home/vagrant/sampleproject/server.sh"

Vagrantで起動したゲストOSを停止した後、再度起動させようとすると共有ディレクトリのマウントで「Failed to mount folders in Linux guest.」エラーが発生する

症状

Vagrantfileがあるディレクトリを/vagrantにマウントされるBoxを使用して、vagrant up

作業ののち、vagrant haltで停止

vagrant upで再度起動すると、

==> default: Mounting shared folders...
    default: /vagrant => D:/Users/hogehoge/vagrant/

のあたりでしばらく止まり

Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3`,dmode=777,fmode=777 vagrant /
vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant`,dmode=777,fmode=777 vagrant /vagrant

The error output from the last command was:

stdin: is not a tty
/sbin/mount.vboxsf: mounting failed with the error: No such device

が出力されて終了する。

原因&解決方法

vagrant – Failed to mount folders in Linux guest. This is usually because the “vboxsf” file system is not available.を直す方法 – Qiita

プロビジョンでパッケージのアップデートを行った際、カーネルもアップデートされたため、VitualBox GuestAdditionをインストールした際の変更がリセットされた。そこで、vagrant-vbguestプラグインを使用して、VitualBox GuestAdditionを再度適用させる。

参考

Windows + VirtualBox 5.0 + Vagrant 1.7.3 でvagrant up時にエラー

上記組み合わせで、vagrant upすると

chown: changing ownership of /vagrant: Not a directory

というエラーで止まってしまいます。

Unable to mount /vagrant folder in 1.7.3 · Issue #5933 · mitchellh/vagrant

より、Vagrant 1.7.4で修正されるようですが、1.7.3を使う場合、

https://github.com/mitchellh/vagrant/issues/5933#issuecomment-120951432 に書かれているように、

C:\HashiCorp\Vagrant\embedded\gems\gems\vagrant-1.7.3\plugins\providers\virtualbox\driver\version_5_0.rb
修正箇所
のようにコメントアウトすることで、一時的に回避できました。

参考

cookbook-anyenvのCentOS7対応とグローバルインストール対応

koba04/cookbooks-anyenvはVagrant+Chefで利用した際、/home/vagrant以下にanyenvをインストールし、anyenvからrbenvなどの*envをインストール、さらにperl,ruby,nodejs,python,phpをインストールしてくれるものです。

レシピ内の依存パッケージがdebianのものになっていてCentOSではインストール時にエラーになり、またanyenvのインストール先を/opt/以下にしたかったため、いくつか変更しました。

変更点

  • CentOSにインストールできるように依存パッケージを追加
  • /home/vagrant以下にインストールするモードと/opt以下にインストールするモードを切り替えられるように
  • プログラミング言語処理系のインストールをせず、明示的に指定するようにした。(デフォルトでは*envはインストールするが、それらを使ってperlなどはインストールしない)

変更したもの: mistymagich/cookbooks-anyenv
デモ: mistymagich/cookbooks-anyenv-demo

nginx cookbookのpassengerレシピのCentOS7対応

nginxのcookbookである miketheman/nginx にはpassengerをモジュールとして追加できるレシピがあります。

そこで、CentOS7上で利用するために、attributeの node[nginx][repo_source]passengernode[‘nginx’][‘install_method’]package に設定してインストールしようとしたところ、

recipes/package.rbには

if platform_family?('rhel')
  if node['nginx']['repo_source'] == 'epel'
    include_recipe 'yum-epel'
  elsif node['nginx']['repo_source'] == 'nginx'
    include_recipe 'nginx::repo'
    package_install_opts = '--disablerepo=* --enablerepo=nginx'
  elsif node['nginx']['repo_source'].to_s.empty?
    log "node['nginx']['repo_source'] was not set, no additional yum repositories will be installed." do
      level :debug
    end
  else
    fail ArgumentError, "Unknown value '#{node['nginx']['repo_source']}' was passed to the nginx cookbook."
  end

としてrepo_source==passengerの選択肢はなく、

recipes/repo_passenger.rb には

case node['platform_family']
when 'rhel', 'fedora'

  log 'There is not official phusion passenger repo for redhat based systems.' do
    level :info
  end

とあり、パッケージリポジトリがない。

また、readme.mdには

Basic configuration to use the official Phusion Passenger repositories:
node['nginx']['repo_source'] – ‘passenger’
node['nginx']['package_name'] – ‘nginx-extras’
node['nginx']['passenger']['install_method'] – ‘package’

とあるが、nginx-extras はCentOSのパッケージにはないため、インストールができない。

一方、PHUSION Passengerの公式ドキュメントには

We provide an official Phusion Passenger YUM repository with packages for Red Hat Enterprise Linux and CentOS.

とあり、パッケージリポジトリが用意されている。そこで、これをrepo_passenger.rbに組み込み、passengerモジュールをインストールする

変更ファイル

  • recipes/package.rb
    プラットフォームファミリーがrhelの場合にrepo_source==’passenger’の選択肢を増やす
  • recipes/repo_passenger.rb
    RHEL,CentOS用のリポジトリファイルを/etc/yum.repos.dにおいて、キャッシュを更新する
  • attributes/passenger.rb
    /etc/nginx/conf.d/passenger.confにあるpassenger_rootの値が違っていたため、プラットフォームファミリーがrhelの場合の時だけ変更する

オリジナルからの変更点一覧: https://github.com/mistymagich/nginx/commit/6327617a066cb09e60703b8dac17fe4c746dc15b?diff=unified

miketheman/nginxをforkして、上記変更を適用したものをmistymagic/nginxに置きました。

またそれを使ってインストールしたpassengerに対して、PHUSION Passengerの公式ドキュメントにあるデモをVagrant+Chefの組み合わせで動かしたデモをmistymagich/nginx-passenger-on-CentOS7-demo
に置きました。

Windowsでberks(Berkshelf)コマンドを実行した際、「”\xA0″ on Windows-31J (Encoding::InvalidByteSequenceError)」エラーが出るとき

現象

Windows上で、ChefDKをインストールし、Berksfileを作成し、

berks vendor cookbooks

のようにしたところ

> berks vendor cookbooks
Resolving cookbook dependencies...
Fetching cookbook index from https://supermarket.chef.io...
C:/opscode/chefdk/embedded/lib/ruby/gems/2.1.0/gems/json-1.8.3/lib/json/common.rb:155:in `encode': "\xA0" on Windows-31J (Encoding::InvalidByteSequenceError)
        from C:/opscode/chefdk/embedded/lib/ruby/gems/2.1.0/gems/json-1.8.3/lib/json/common.rb:155:in `initialize'
        from C:/opscode/chefdk/embedded/lib/ruby/gems/2.1.0/gems/json-1.8.3/lib/json/common.rb:155:in `new'
        from C:/opscode/chefdk/embedded/lib/ruby/gems/2.1.0/gems/json-1.8.3/lib/json/common.rb:155:in `parse'
        from C:/opscode/chefdk/embedded/lib/ruby/gems/2.1.0/gems/ridley-4.2.0/lib/ridley/chef/cookbook/metadata.rb:473:in `from_json'
        from C:/opscode/chefdk/embedded/lib/ruby/gems/2.1.0/gems/ridley-4.2.0/lib/ridley/chef/cookbook/metadata.rb:29:in `from_json'
        from C:/opscode/chefdk/embedded/lib/ruby/gems/2.1.0/gems/ridley-4.2.0/lib/ridley/chef/cookbook.rb:36:in `from_path'
        from C:/opscode/chefdk/embedded/apps/berkshelf/lib/berkshelf/cached_cookbook.rb:15:in `from_store_path'
        from C:/opscode/chefdk/embedded/apps/berkshelf/lib/berkshelf/cookbook_store.rb:108:in `block in cookbooks'
        from C:/opscode/chefdk/embedded/apps/berkshelf/lib/berkshelf/cookbook_store.rb:98:in `collect'
        from C:/opscode/chefdk/embedded/apps/berkshelf/lib/berkshelf/cookbook_store.rb:98:in `cookbooks'
        from C:/opscode/chefdk/embedded/apps/berkshelf/lib/berkshelf/resolver/graph.rb:8:in `populate_store'
        from C:/opscode/chefdk/embedded/apps/berkshelf/lib/berkshelf/resolver.rb:73:in `resolve'
        from C:/opscode/chefdk/embedded/apps/berkshelf/lib/berkshelf/installer.rb:175:in `install_from_universe'
        from C:/opscode/chefdk/embedded/apps/berkshelf/lib/berkshelf/installer.rb:39:in `run'
        from C:/opscode/chefdk/embedded/apps/berkshelf/lib/berkshelf/berksfile.rb:374:in `install'
        from C:/opscode/chefdk/embedded/apps/berkshelf/lib/berkshelf/berksfile.rb:583:in `block in vendor'
        from C:/opscode/chefdk/embedded/lib/ruby/2.1.0/tmpdir.rb:88:in `mktmpdir'
        from C:/opscode/chefdk/embedded/apps/berkshelf/lib/berkshelf/berksfile.rb:581:in `vendor'
        from C:/opscode/chefdk/embedded/apps/berkshelf/lib/berkshelf/cli.rb:387:in `vendor'
        from C:/opscode/chefdk/embedded/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/command.rb:27:in `run'
        from C:/opscode/chefdk/embedded/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in `invoke_command'
        from C:/opscode/chefdk/embedded/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor.rb:359:in `dispatch'
        from C:/opscode/chefdk/embedded/apps/berkshelf/lib/berkshelf/cli.rb:52:in `dispatch'
        from C:/opscode/chefdk/embedded/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/base.rb:440:in `start'
        from C:/opscode/chefdk/embedded/apps/berkshelf/lib/berkshelf/cli.rb:27:in `execute!'
        from C:/opscode/chefdk/embedded/apps/berkshelf/bin/berks:5:in `<top (required)>'
        from C:/opscode/chefdk/bin/berks:43:in `load'
        from C:/opscode/chefdk/bin/berks:43:in `<main>'

というエラーが発生

対策

「C:\opscode\chefdk\bin\berks」 を開き、3行目に

Encoding.default_external = 'utf-8'

を追加する。

参考

WindowsにインストールしたVagrantにMinGWをインストールして、rsyncコマンドインストールする

Vagrantfile中に

config.vm.synced_folder "../app", "/var/www/app", type: "rsync"

のような同期フォルダのオプションでrsyncを使用したいため、rsyncを導入したときのメモ

Vagrantの組み込み実行ファイル領域(C:HashiCorpVagrantembedded)にrsyncをインストールして、vagrant up中にrsyncが利用できるようにする。

前提

  • Vagrantは「C:HisashiCorp」にインストールしている

インストール手順

  1. MinGWをインストールする。インストール先はデフォルトの「C:MinGW」
  2. 「C:MinGW以下」(binなどのディレクトリ)のファイル、ディレクトリを「C:HashiCorpVagrantembedded」に上書きコピー
  3. 「C:HashiCorpVagrantembeddedvarlibmingw-getdata」の【profile.xml】・【defaults.xml】を編集
    deraults.xml

    @@ -130,7 +130,7 @@
           default, irrespective of its actual "id" attribute value.
         -->
         <sysroot subsystem="mingw32" path="%R" />
    -    <sysroot subsystem="MSYS" path="%R/msys/1.0" />
    +    <sysroot subsystem="MSYS" path="/HashiCorp/Vagrant/embedded" />
       </system-map>
    
     </profile>
    

    profile.xml

    @@ -132,3 +132,3 @@
         <sysroot subsystem="mingw32" path="%R" />
    -    <sysroot subsystem="MSYS" path="%R/msys/1.0" />
    +    <sysroot subsystem="MSYS" path="/HashiCorp/Vagrant/embedded" />
       </system-map>
    
  4. mingw-getコマンドでssh,rsyncをインストール(>はコマンドプロンプト)
    > C:HashiCorpVagrantembeddedbinmingw-get.exe update
    > C:HashiCorpVagrantembeddedbinmingw-get.exe install msys-openssh msys-rsync
    

操作手順

D:\work\project\envディレクトリにVagrantfileがあり、D:\work\project\appディレクトリをゲストOS上の/var/www/appに同期したいとき。
Vagrantfileの記述は冒頭のもの。

  1. vagrant upでVagrant起動
  2. ゲストOSが起動したら、vagrant rsync-autoでホストファイル上の共有フォルダを監視状態にする
    > vagrant rsync-auto
    ==> default: Doing an initial rsync...
    ==> default: Rsyncing folder: /d/work/project/app/ => /var/www/app
    ==> default: Watching: D:/work/project/app
    D, [2015-07-01T15:21:19.682053 #4564] DEBUG -- : Adapter: considering TCP ...
    D, [2015-07-01T15:21:19.682053 #4564] DEBUG -- : Adapter: considering polling ...
    D, [2015-07-01T15:21:19.683030 #4564] DEBUG -- : Adapter: considering optimized backend...
    
  3. 共有フォルダ内のファイルを編集後保存すると、自動的にゲストOS側に転送される。
    ==> default: Rsyncing folder: /d/work/project/app/ => /var/www/app
    

    でゲストOSに反映

参考