I have a vagrant provisioning script which succeeds -- I can see the output from the logs and my dependencies are being installed, my directories and files are being created and copied over, etc. but when I vagrant ssh into the VM none of the folders, files, env variables, and installations are there.
Edit: git, curl, etc. work, but gvm, go, and $GOPATH etc do not, and my go directory does not exist
I'm confident the provisioning works correctly because I can run my web server from the script and confirm the application is being served.
Is this just the way Vagrant is set up? What's the point of vagrant ssh if so?
I'm running the default "hashicorp/precise32" box, Ubuntu 12.04, default provider.
Shell script
#! /bin/bash
echo "Provisioning virtual machine"
sudo apt-get update
echo "Installing Dependencies"
# Base dependencies: curl git
# Dependencies for gvm: make bison
sudo apt-get install curl git make bison -y 2> /dev/null
# Dependencies for add-apt-repository: python-software-properties software-properties-common
sudo apt-get install python-software-properties software-properties-common -y 2> /dev/null
# This allows us to get an updated version of git, which we need for gvm
sudo add-apt-repository ppa:git-core/ppa -y 2> /dev/null
sudo apt-get update
sudo apt-get install git -y 2> /dev/null
echo "Installing GVM"
bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
source ~/.gvm/scripts/gvm
echo "Installing and configuring Go"
gvm install go1.4
gvm use go1.4 --default
mkdir -p ~/go/{bin,pkg,src}
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
echo "Installing Nginx"
sudo apt-get install nginx -y 2> /dev/null
Vagrantfile
`# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
config.vm.box = "hashicorp/precise32"
config.vm.provision :shell, path: "init.sh"
config.vm.network :forwarded_port, host: 4000, guest: 8080
end`
The Vagrant provisioning script is running as root, so ~ refers to /root instead of /home/vagrant.
Options to resolve are su -c "*your command*" vagrant or using absolute paths, which is probably the best approach.
Similar issue: Why is my Vagrant bootstrap file not modifying bash_login?
And more detail in my answer here: Vagrant - Rails Not Installed
Related
I'm using this vagrantfile:
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "ubuntu/trusty64"
...bla bla bla bla bla...
config.vm.provision "shell", path: "provision/setup.sh"
end
Since I want to install Linuxbrew I have in my provision/setup.sh this code:
sudo apt-get update
sudo apt-get install --yes git-all libreadline-dev build-essential curl git m4 python-setuptools ruby texinfo libbz2-dev libcurl4-openssl-dev libexpat-dev libncurses-dev zlib1g-dev
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/linuxbrew/go/install)"
# or maybe also this: (but nothing anyway):
# sudo git clone https://github.com/Linuxbrew/linuxbrew.git /home/vagrant/.linuxbrew
export PATH=$HOME/.linuxbrew/bin:$PATH
brew doctor
But I retrieve errors:
==> default: /tmp/vagrant-shell: line 35: brew: command not found
How to fix this?
There's an issue how you run your script - as you run with config.vm.provision "shell", path: "provision/setup.sh" vagrant will run it as root user and so you do not need sudo
however you should really run it as your user so do config.vm.provision "shell", path: "provision/setup.sh", privileged: false
also the export will not be saved for your future session so add it to .bashrc file something like echo PATH=$HOME/.linuxbrew/bin:$PATH >> .bashrc so the final script would look like
sudo apt-get update
sudo apt-get install --yes git-all libreadline-dev build-essential curl git m4 python-setuptools ruby texinfo libbz2-dev libcurl4-openssl-dev libexpat-dev libncurses-dev zlib1g-dev
yes | ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/linuxbrew/go/install)"
echo PATH=$HOME/.linuxbrew/bin:$PATH >> ~/.bashrc
export PATH=$HOME/.linuxbrew/bin:$PATH
brew doctor
The export is needed if you run brew from the script but note that brew doctor will likely ends up with warning and do not return so you might end up seeing vagrant message as
The SSH command responded with a non-zero exit status. Vagrant
assumes that this means the command failed. The output for this command
should be in the log above. Please read the output to determine what
went wrong.
and finally for the original error, #BMW gets all credit adding yes | to the command will default the enter key on the question
Let me guess. Add yes before the ruby command
yes | ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/linuxbrew/go/install)"
I'm using this vagrantfile:
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "ubuntu/trusty64"
...bla bla bla bla bla...
config.vm.provision "shell", path: "provision/setup.sh", privileged: false
end
In my setup.sh I have:
sudo apt-get update
sudo apt-get install --yes git-all libreadline-dev build-essential curl git m4 python-setuptools ruby texinfo libbz2-dev libcurl4-openssl-dev libexpat-dev libncurses-dev zlib1g-dev
yes | ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/linuxbrew/go/install)"
echo PATH=$HOME/.linuxbrew/bin:$PATH >> ~/.bashrc
export PATH=$HOME/.linuxbrew/bin:$PATH
brew doctor
then I have:
brew install rbenv ruby-build
brew update
brew upgrade
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
. ~/.bashrc
rbenv init
rbenv install 2.3.0
rbenv global 2.3.0
rbenv local 2.3.0
rbenv versions
gem install bundler
but I receive this error:
==> default: ERROR: While executing gem ... (Errno::EACCES) ==> default: Permission denied - /var/lib/gems`
How can I install "bundler" and other "gems" with my setup script?
It's not a good idea to run sudo in a script, but try sudoing the script itself with
$ sudo ./script.sh
and take all your 'sudos' out of your sh script.
Next change
config.vm.provision "shell", path: "provision/setup.sh", privileged: false
to
config.vm.provision "shell", path: "provision/setup.sh", privileged: true
This way sudo is only unlocked for the file, and it has control for whatever you are doing.
If this is a new file in the machine, you may need to use
chmod +x ./script.sh
for your os to execute it properly. From what I see, things should work okay unless you have accidentally provisioned your vm twice in which you may want to override it. You also can try running each command yourself to see if it is an isolated issue outside of vagrant.
edit:
The main issue is that the /var/lib/gems directory is own by root, so by whatever means get that under the sudo command.
edit: Massive clarity.
When running my docker container it knows rbenv global. But when ever it try to find ruby via ruby or which ruby or whereis ruby I get nothing. It also doesn't recognize rails-api or gem. What is going on?
Dockerfile
FROM centos:6.6
RUN yum update -y
RUN yum install git openssl-devel openssh-server sudo openssl readline-devel readline zlib-devel zlib libxml2-devel libxml2 libxslt-devel libxslt nginx tar gcc libaio libaio-devel -y
RUN rpm -Uvh https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-12.5.1-1.el6.x86_64.rpm
RUN sed -i -e "s/Defaults requiretty.*/ #Defaults requiretty/g" /etc/sudoers
RUN mkdir -p /var/run/sshd
RUN useradd -m -u 1000 -G wheel deploy && echo '%wheel ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers.d/wheel
USER deploy
RUN mkdir ~/dev
RUN git clone https://github.com/sstephenson/rbenv.git ~/.rbenv/
RUN git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
ENV PATH ~/.rbenv/bin:$PATH
RUN echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
RUN source ~/.bash_profile
ENV CONFIGURE_OPTS --disable-install-doc
RUN rbenv install 2.2.3
RUN rbenv global 2.2.3
RUN bash -l -c 'gem update --system'
RUN bash -l -c 'gem update'
RUN bash -l -c 'gem install nokogiri -- --use-system-libraries'
RUN bash -l -c 'gem install bundler rails-api --no-rdoc --no-ri'
COPY oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm /tmp/oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm
COPY oracle-instantclient12.1-devel-12.1.0.2.0-1.x86_64.rpm /tmp/oracle-instantclient12.1-devel-12.1.0.2.0-1.x86_64.rpm
COPY oracle-instantclient12.1-sqlplus-12.1.0.2.0-1.x86_64.rpm /tmp/oracle-instantclient12.1-sqlplus-12.1.0.2.0-1.x86_64.rpm
RUN sudo rpm -Uvh /tmp/oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm
RUN sudo rpm -Uvh /tmp/oracle-instantclient12.1-devel-12.1.0.2.0-1.x86_64.rpm
RUN sudo rpm -Uvh /tmp/oracle-instantclient12.1-sqlplus-12.1.0.2.0-1.x86_64.rpm
RUN sudo touch /etc/sysconfig/network
RUN NLS_LANG=American_America.UTF8
ENV ORACLE_HOME=/usr/lib/oracle/12.1/client64
ENV LD_LIBRARY_PATH=/usr/lib/oracle/12.1/client64/lib
EXPOSE 22
EXPOSE 3000
EXPOSE 5000
The issue at hand here is that every RUN statement in the Dockerfile happens in its own environment. The RUN source ~/.bash_profile will set $PATH to have /root/.rbenv/shims in it. But subsequent RUN will not have this environment set as they won't source .bash_profile since this isn't an interactive shell.
The easy way to solve this is to just add a ENV PATH $HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH somewhere before the ruby and gem commands. This is really the only bit you should need from the rbenv init shell script.
Have you tried rbenv rehash after installing the new Ruby version?
Your Dockerfile only uses one version of Ruby. Given your use case, I would recommend just using the official ruby docker images: https://hub.docker.com/_/ruby
I'm playing with boot2docker (docker 1.6) on windows 8.1. I wanted to make myself machine container to play with ruby and I want to be able to connect to rails server from my windows host. To start with small steps first I want to connect to my container from my boot2docker VM. I attach my docker file below, it builds without a problem and I can run a container from it. I do it like so:
docker run -it -p 3000:3000 3564860f7afd /bin/bash
Then in this container I say:
cd ~/myapp && bundle exec rails server -d
And to see if everything is working I do:
~/myapp$ sudo apt-get install wget && wget localhost:3000
and I get http 500, which is ok, I just wanted to check if server is running. Then I exit using ctrl+p, ctrl+q. But then on boot2docker machine I do agin
wget localhost:3000
and get
Connecting to localhost:3000 (127.0.0.1:3000)
wget: error getting response: Connection reset by peer
So it seems like port 3000 is not correctly forwarded to boot2docker VM. What have I done wrong? What did I miss? I googled extensively and tried couple of things like explicitly exposing port from dockerfile of or adding -P switch to run, but I always end up the same way - it's not working.
Any help will be greatly appreciated.
UPDATE 02.05.2015
I have also tried things described in comment from Markus W Mahlberg and reponse from VonC. My VM configuration seems to be ok, I also checked in GUI of VirtualBox and it seems fine. Some more info: When I start
boot2docker ssh -vnNTL 3000:localhost:3000
and then open localhost:3000 on my windows host I see in trace logs in boot2docker console, they look like this:
debug1: channel 1: free: direct-tcpip: listening port 3000 for localhost port 3000, connect from 127.0.0.1 port 50512 to 127.0.0.1 port 3000, nchannels 3
Chrome tells me that the response was empty. From checking the logs on container I know that request never got to it.
End of update
Update 03.05.2015
I thing that my problem have not so much to do with boot2docker or docker as with my computer configuration. I've been over my docker/boot2docker configuration so many times, that it is rather unlikely that I've made a mistake there.
Desperately I've reinstalled boot2docker and VirtualBox, still no effects. Any ideas how to debug what can be wrong with my configuration? Only other idea I have is to try doing the same on another machine. But even if this works my original problem is no less annoying.
End of update
Here is my dockerfile:
FROM ubuntu
MAINTAINER anonymous <anonymous#localhost.com>
LABEL Description="Ruby container"
# based on https://gorails.com/setup/ubuntu/14.10
RUN apt-get update
RUN apt-get -y upgrade
RUN apt-get -y install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \
&& groupadd anonymous \
&& useradd anonymous -m -g anonymous -g sudo
ENV HOME /home/anonymous
USER anonymous
RUN git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
RUN echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
RUN echo 'eval "$(rbenv init -)"' >> ~/.bashrc
RUN exec $SHELL
RUN git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
RUN echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
RUN exec $SHELL
RUN git clone https://github.com/sstephenson/rbenv-gem-rehash.git ~/.rbenv/plugins/rbenv-gem-rehash
ENV PATH "$HOME/.rbenv/bin:$HOME/.rbenv/plugins/ruby-build/bin:$PATH"
RUN rbenv install 2.2.1
RUN rbenv global 2.2.1
ENV PATH "$HOME/.rbenv/shims:$PATH"
RUN echo 'gem: --no-ri --no-rdoc' > ~/.gemrc
RUN gem install bundler
RUN git config --global color.ui true
RUN git config --global user.name "mindriven"
RUN git config --global user.email "3dcreator.pl#gmail.com"
RUN ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa -C "3dcreator.pl#gmail.com"
RUN sudo apt-get -qy install software-properties-common python-software-properties
RUN sudo add-apt-repository ppa:chris-lea/node.js
RUN sudo apt-get -y install nodejs
RUN gem install rails -v 4.2.0
RUN ~/.rbenv/bin/rbenv rehash
RUN rails -v
RUN sudo apt-get -qy install mysql-server mysql-client
RUN sudo apt-get install libmysqlclient-dev
RUN rails new ~/myapp -d mysql
RUN sudo /etc/init.d/mysql start && cd ~/myapp && rake db:create
See Boot2docker workarounds:
You can use VBoxManage.exe commands to open those ports on the boot2docker VM level, in order for your actual VM host to access them.
By default, only the port 2222 is open, for boot2docker ssh to work and open an interactive ssh boot2docker session.
Just make sure VirtualBox is in your PATH.
VBoxManage modifyvm: works when the boot2docker VM isn't started yet, or after a boot2docker stop,
VBoxManage controlvm: works when the boot2docker VM is running, after a boot2docker start.
Let's say your Docker container exposes the port 8000 and you want access it from your other computers on your LAN. You can do it temporarily, using ssh:
Run following command (and keep it open):
$ boot2docker ssh -vnNTL 8000:localhost:8000
or you can set up a permanent VirtualBox NAT Port forwarding:
$ VBoxManage modifyvm "boot2docker-vm" --natpf1 "tcp-port8000,tcp,,8000,,8000";
If the vm is already running, you should run this other command:
$ VBoxManage controlvm "boot2docker-vm" natpf1 "tcp-port8000,tcp,,8000,,8000";
Now you can access your container from your host machine under
localhost:8000
That way, you don't have to mess around with the VirtualBox GUI, selecting the computer called boot2docker-vm from the list on the left, choosing Settings from the Machine menu (or press Command-S on a Mac), selecting the Network icon at the top, and finally clicking the Port Forwarding button.
boot2docker on Windows (and OSX) is running a VirtualBox VM with Linux in it. By default it exposes only the ports necessary to ssh into the VM. You'll need to modify the VM to get it to expose more ports.
Adding ports to the VM is more about configuring VirtualBox and less about boot2docker (it is a property of the VM, not the software running inside it). Please see the VirtualBox documentation for "port forwarding" and other network configuration. https://www.virtualbox.org/manual/ch06.html
Yes you need to open the ports in the Virtualbox machines:
enter image description here
I am not sure if I should use Puppet for this. I update and install through provision.sh.
My Vagrantfile
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu32"
config.vm.provision :shell, path: './provision.sh'
config.vm.network "public_network"
end
provision.sh
apt-get update
apt-get -y install build-essential git-core python-software-properties nodejs
apt-get -y install vim
apt-get -y install curl
curl https://raw.github.com/fesplugas/rbenv-installer/master/bin/rbenv-installer | bash
Now I need to add the following to ~/.bashrc at the top. Or I can prepare a file .bashrc and replace it with ~/.bashrc
export RBENV_ROOT="${HOME}/.rbenv"
if [ -d "${RBENV_ROOT}" ]; then
export PATH="${RBENV_ROOT}/bin:${PATH}"
eval "$(rbenv init -)"
fi
Then run source .bashrc
Then run following commands.
rbenv install 2.0.0-p247
rbenv rehash
gem install bundler
bundle
sudo apt-get install libpq-dev
gem install pg -v '0.15.0'
You can do this in your provision.sh script. Vagrant automatically shares the directory where your Vagrantfile lives with the guest VM as the /vagrant folder.
Create the .bashrc file as you want it, and put it in the same directory as your Vagrantfile. I would leave out the '.' and call it bashrc so you don't loose track of it.
Then you can add to your provision.sh script:
cp /vagrant/bashrc ~/.bashrc
source ~/.bashrc
Note: the bash provisioning runs as the root user, you'll have to modify this a bit if you want to use it as a non-root user.
cp /vagrant/bashrc /home/<username>/.bashrc
su - <username> -c "<command to run as user>"