Vagrant/VirtualBox VM provisioning: rbenv installs successfully but subsequent uses in script fail

前端 未结 3 952
南笙
南笙 2020-12-25 08:56

I am using Vagrant + VirtualBox to set up a virtual machine for my Rails app. I am working on cleaning up a .sh provisioning script that is referenced in

相关标签:
3条回答
  • 2020-12-25 09:21

    I had a similar problem because I was trying to install rbenv and the vagrant provisioning was giving me the error:

    ==> default: /tmp/vagrant-shell: line 10: rbenv: command not found
    

    First of all, it is very important to understand that vagrant provisioning script is running in sudo mode. So, when in the script we refer to ~/ path, we are referring to /root/ path and not to /home/vagrant/ path. The problem is that I was installing rbenv for the root user and after trying to call rbenv command from a vagrant user and, of course, it didn't work!

    So, what I did is specify the vagrant to run the provisioner NOT in sudo user, adding privileged: false:

    config.vm.provision :shell, privileged: false, inline: $script
    

    Then in my script I considered everything as being called from the vagrant user. Here @Casper answer helped me a lot, because it works only specifying: 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.

    Below is my final 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
    

    Hope it will be helpful to someone else.

    0 讨论(0)
  • 2020-12-25 09:29

    I'm surprised the provisioning script exits, as running su vagrant should in theory hang the script at that point (you're running the command su which does not normally exit by itself).

    The problem is you cannot change the user that is running a shell script "on the fly" by running su.
    Your only option is to use sudo.

    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.

    So, something like this should hopefully work:

    echo "building ruby"
    sudo -H -u vagrant bash -i -c 'rbenv install 2.2.1 ...'
    
    0 讨论(0)
  • 2020-12-25 09:34

    There another Solution to install rbenv within Vagrant Provisioning process different than both @Casper and @Diego D solutions.

    Using Next Commands before using rbenv commands

    export PATH="$HOME/.rbenv/bin:$PATH"
    export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"
    eval "$(rbenv init -)"
    

    Then run rbenv install commands without sudo -H -u vagrant bash -i -c

    Bootstrap.sh File

    #!/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
    
    

    Then VagrantFile file will include vagrant provisioning line

    deploy_config.vm.provision :shell, privileged: false, path: "bootstrap.sh"
    

    Source for my Answer from Gits by @creisor

    0 讨论(0)
提交回复
热议问题