我正在使用 Vagrant + VirtualBox 为我的 Rails 应用设置虚拟机。我正在清理 Vagrantfile 中引用的 .sh 配置脚本,如下所示:
config.vm.provision "shell", path: "script/provision-script.sh"
配置脚本做了很多事情,但最后它应该安装 rbenv Ruby 版本控制,然后使用 rbenv 安装 Ruby 2.2.1。供应脚本的那部分看起来像这样:
echo "setting up rbenv"
# execute the remaining commands as vagrant user, instead of root
sudo -H -u vagrant bash -c "git clone https://github.com/sstephenson/rbenv.git ~vagrant/.rbenv"
sudo -H -u vagrant bash -c "git clone https://github.com/sstephenson/ruby-build.git ~vagrant/.rbenv/plugins/ruby-build"
sudo -H -u vagrant bash -c "git clone https://github.com/sstephenson/rbenv-gem-rehash.git ~vagrant/.rbenv/plugins/rbenv-gem-rehash"
echo "setting up rbenv environment in bash"
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~vagrant/.bashrc
echo 'eval "$(rbenv init -)"' >> ~vagrant/.bashrc
# start new vagrant shell so rbenv will work
echo "building ruby"
su vagrant
rbenv install 2.2.1 && rbenv global 2.2.1 && rbenv rehash && cd /path/to/my/app && gem install bundler rake && rbenv rehash && bundle && rbenv rehash
rbenv install... 部分之前的所有内容都可以正常工作。安装 ruby 失败并出现以下错误:
==> default: setting up rbenv
==> default: Cloning into '/home/vagrant/.rbenv'...
==> default: Cloning into '/home/vagrant/.rbenv/plugins/ruby-build'...
==> default: Cloning into '/home/vagrant/.rbenv/plugins/rbenv-gem-rehash'...
==> default: setting up rbenv environment in bash
==> default: building ruby
==> default: /tmp/vagrant-shell: line 73: rbenv: command not found
然后脚本结束。我可以使用 vagrant ssh 打开虚拟机,然后成功运行 rbenv install 2.2.1,所以我猜测在配置期间实际上并没有启动新的 vagrant shell。我的印象是,这应该在 rbenv install 2.2.1 之前发生在 su vagrant 上。
我该怎么做才能确保在此配置期间初始化新的 shell 并确保 rbenv 命令正常工作?
最佳答案
我遇到了类似的问题,因为我正在尝试安装 rbenv 并且 vagrant provisioning 给我错误:
==> default: /tmp/vagrant-shell: line 10: rbenv: command not found
首先,了解 vagrant provisioning 脚本以 sudo 模式运行是非常重要的。 因此,当我们在脚本中引用 ~/路径时,我们指的是/root/路径而不是/home/vagrant/路径。 问题是我正在为 root 用户安装 rbenv,并在尝试从 vagrant 用户调用 rbenv 命令后,当然,它没有工作!
所以,我所做的是指定 vagrant 不在 sudo 用户中运行配置程序,添加 privileged: false:
config.vm.provision :shell, privileged: false, inline: $script
然后在我的脚本中,我认为一切都是从 vagrant 用户调用的。 这里@Casper 的回答对我帮助很大,因为它只适用于指定: sudo -H -u vagrant bash -i -c '......'
Since you just updated .bashrc with a new path and other settings, you will want to run "sudo bash" with the -i option. This will force bash to simulate an interactive login shell, and therefore read .bashrc and load the correct path for rbenv.
下面是我最终的 Vagrantfile。
# -*- mode: ruby -*-
# vi: set ft=ruby :
$script = <<SCRIPT
sudo apt-get -y update
sudo apt-get -y install curl git-core python-software-properties ruby-dev libpq-dev build-essential nginx libsqlite3-0 libsqlite3-dev libxml2 libxml2-dev libxslt1-dev nodejs postgresql postgresql-contrib imagemagick
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
sudo -H -u vagrant bash -i -c 'rbenv install 2.1.3'
sudo -H -u vagrant bash -i -c 'rbenv rehash'
sudo -H -u vagrant bash -i -c 'rbenv global 2.1.3'
sudo -H -u vagrant bash -i -c 'gem install bundler --no-ri --no-rdoc'
sudo -H -u vagrant bash -i -c 'rbenv rehash'
sudo -u postgres createdb --locale en_US.utf8 --encoding UTF8 --template template0 development
echo "ALTER USER postgres WITH PASSWORD \'develop\';" | sudo -u postgres psql
SCRIPT
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "hashicorp/precise64"
config.vm.network "forwarded_port", guest: 3000, host: 3000
# config.vm.provider :virtualbox do |vb|
# vb.customize ["modifyvm", :id, "--memory", "1024"]
# end
config.vm.provision :shell, privileged: false, inline: $script
end
希望对其他人有所帮助。
关于ruby-on-rails - Vagrant/VirtualBox VM 配置 : rbenv installs successfully but subsequent uses in script fail,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29132891/