# Project VM Deployment

The project in this course may be deployed on a virtual machines that is provisioned (by Vagrant) and configured (by Chef or similar) automatically.

## Getting Set Up: your computer

You should be able to use any OS on your computer to set up the VMs: both of the tools we need are supported on Linux, OSX, and Windows.

Your computer needs to be powerful enough to do whatever you are using it for (web browser, IDE, etc.), plus provide resources to a small virtual machine.

1. Install VirtualBox. You can do this in Windows, OSX, or Linux. In Ubuntu, this can by done by installing the package virtualbox (or virtualbox-qt if you want the GUI tools too).
2. Install Vagrant. You can also do this in Windows, OSX, or Linux. In Ubuntu, install the vagrant package.
3. Get the template code for the project from the project template repository.

If you try to start a virtual machine and it seems to hang, you can try starting a VM from the VirtualBox GUI: you can see error messages there. The most likely cause is not having processor virtualization extensions, either because they're off in your BIOS, or because you're trying to run a VM inside another VM.

If you are having problems getting any VM to start, you have have your processor's virtualization extensions turned off in the BIOS. (This seems to be common in some laptops.) It should be easy enough to enable the extension.

## Working with VMs

The vagrant command is used to work with your virtual machine.

• vagrant up: Start the VM, using configuration from the Vagrantfile in the current directory. The first time you start a particular VM, this might take a while: it will download the box image and provision the VM.
• vagrant provision: Re-run the provisioner (Chef) recipe on the VM. This will need to be done if you update the recipes.
• vagrant ssh: SSH in to the VM so you get a command line there.
• vagrant halt: Shut down the VM.
• vagrant destroy: Destroy the VM image. You should be able to recreate it by doing a vagrant up and letting it provision itself.

## Working with Chef

Chef is a configuration management tool that is used to install/configure a system into a well-defined and reproducible state.

In the provided template, the file cookbooks/polyglot/recipes/default.rb is doing most of the work. Most of it is commented out and you can un-comment parts as necessary to install language tools or libraries as described there.

If you need other libraries (e.g. Ruby on Rails, a Go package for some numeric computation), hopefully you can do it by analogy with the commented code in the recipe.

## Port Forwarding and Servers

If you have a server (web server, RPC server, etc), you can make it accessible outside the VM by uncommenting one of the lines like this in your Vagrantfile (in this example, port 80 on your VM to port 8080 outside):

config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"


With that in your Vagrantfile, you should be able to access the VM's port 80 at port 8080 on you computer; if it's a web server, at the URL http://localhost:8080/ .

The server running inside your VM must be listening to connections from the outside, not just localhost connections (like many development servers do). In general, you want to “listen on all interfaces” and searching for that phrase (and the name of you tool/framework) will probably turn something up, but a few examples for common web frameworks:

rails server -b 0.0.0.0                   # Ruby on Rails
python3 manage.py runserver 0.0.0.0:8000  # Django
php artisan serve --host 0.0.0.0          # Laravel


## Compiling and Starting Services

If you have compilation or other setup commands that need to run when bringing up your project, you can add an execute block to the Chef recipe to run them. For example, if you need to run make project in your project directory to compile some code, the default.rb block would be like this:

execute 'make project' do
cwd project_home
environment 'HOME' => user_home
end


Or if you have a server that needs to be started in the background (in this example, with the command “python3 rpc_server.py”):

execute 'python3 rpc_server.py &' do
cwd project_home

execute 'screen -dm python3 rpc_server.py' do