Vagrant/VirtualBox VM 配置:rbenv 安装成功但随后在脚本中的使用失败
Vagrant/VirtualBox VM provisioning: rbenv installs successfully but subsequent uses in script fail
我正在使用 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。我的印象是 su vagrant
就在 rbenv install 2.2.1
之前。
我该怎么做才能确保在此配置期间初始化新的 shell 并确保 rbenv
命令有效?
我很惊讶配置脚本会退出,因为 运行ning su vagrant
理论上应该在那个时候挂起脚本(你 运行ning 命令 su
通常不会自行退出)。
问题是您无法通过 运行ning su
.[=28= 更改正在 运行ning shell 脚本 "on the fly" 的用户]
您唯一的选择是使用 sudo
.
由于您刚刚使用新路径和其他设置更新了 .bashrc
,因此您需要 运行 "sudo bash"
使用 -i
选项。这将强制 bash 模拟交互式登录 shell,因此读取 .bashrc
并加载 rbenv
.
的正确路径
所以,像这样的东西应该会起作用:
echo "building ruby"
sudo -H -u vagrant bash -i -c 'rbenv install 2.2.1 ...'
我遇到了类似的问题,因为我试图 安装 rbenv 并且 vagrant provisioning 给我错误:
==> default: /tmp/vagrant-shell: line 10: rbenv: command not found
首先,了解 vagrant 供应脚本 运行 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
希望对其他人有所帮助。
在 Vagrant Provisioning 过程中安装 rbenv
的另一个解决方案不同于两个 and 解决方案。
在使用 rbenv
命令之前使用下一个命令
export PATH="$HOME/.rbenv/bin:$PATH"
export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"
eval "$(rbenv init -)"
然后 运行 rbenv
安装命令而不 sudo -H -u vagrant bash -i -c
Bootstrap.sh 文件
#!/usr/bin/env bash
sudo apt-get update
echo "========================= install dependencies for install rbenv ==========================="
sudo apt-get install -y autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev
echo "========================= install rbenv =========================================="
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
echo "========================= install ruby build plugin for rbenv ======================="
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
echo "========================= install ruby v2.5.0 =========================================="
export PATH="$HOME/.rbenv/bin:$PATH"
export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"
eval "$(rbenv init -)"
rbenv install 2.5.0
rbenv global 2.5.0
ruby -v
gem -v
echo "========================= install bundler dependencies manager for ruby ====================="
gem install bundler
rbenv rehash
然后 VagrantFile
文件将包含 vagrant 配置行
deploy_config.vm.provision :shell, privileged: false, path: "bootstrap.sh"
我的答案来自 Gits by @creisor
我正在使用 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。我的印象是 su vagrant
就在 rbenv install 2.2.1
之前。
我该怎么做才能确保在此配置期间初始化新的 shell 并确保 rbenv
命令有效?
我很惊讶配置脚本会退出,因为 运行ning su vagrant
理论上应该在那个时候挂起脚本(你 运行ning 命令 su
通常不会自行退出)。
问题是您无法通过 运行ning su
.[=28= 更改正在 运行ning shell 脚本 "on the fly" 的用户]
您唯一的选择是使用 sudo
.
由于您刚刚使用新路径和其他设置更新了 .bashrc
,因此您需要 运行 "sudo bash"
使用 -i
选项。这将强制 bash 模拟交互式登录 shell,因此读取 .bashrc
并加载 rbenv
.
所以,像这样的东西应该会起作用:
echo "building ruby"
sudo -H -u vagrant bash -i -c 'rbenv install 2.2.1 ...'
我遇到了类似的问题,因为我试图 安装 rbenv 并且 vagrant provisioning 给我错误:
==> default: /tmp/vagrant-shell: line 10: rbenv: command not found
首先,了解 vagrant 供应脚本 运行 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
希望对其他人有所帮助。
在 Vagrant Provisioning 过程中安装 rbenv
的另一个解决方案不同于两个
在使用 rbenv
命令之前使用下一个命令
export PATH="$HOME/.rbenv/bin:$PATH"
export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"
eval "$(rbenv init -)"
然后 运行 rbenv
安装命令而不 sudo -H -u vagrant bash -i -c
Bootstrap.sh 文件
#!/usr/bin/env bash
sudo apt-get update
echo "========================= install dependencies for install rbenv ==========================="
sudo apt-get install -y autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev
echo "========================= install rbenv =========================================="
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
echo "========================= install ruby build plugin for rbenv ======================="
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
echo "========================= install ruby v2.5.0 =========================================="
export PATH="$HOME/.rbenv/bin:$PATH"
export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"
eval "$(rbenv init -)"
rbenv install 2.5.0
rbenv global 2.5.0
ruby -v
gem -v
echo "========================= install bundler dependencies manager for ruby ====================="
gem install bundler
rbenv rehash
然后 VagrantFile
文件将包含 vagrant 配置行
deploy_config.vm.provision :shell, privileged: false, path: "bootstrap.sh"
我的答案来自 Gits by @creisor