ARCHIVE

As promised on Twitter, I’m going to explain how I’m now using Vagrant to develop Gitrepos instead of running it on my development Macbook Air.

Technical debt

Against my better judgment, I started developing Gitrepos on my Mac without bothering with creating an Ubuntu VM running on VMWare Fusion as I did for other projects in the past. At the time, I figured that if I used the correct libraries and abstracting my code enough, I could develop with PHP built-in server and SQLite. I already wrote here that I don’t like running servers on my Mac for 2 reasons:

  • It’s a security risk I don’t want to be bothered with. I don’t want to check the servers are protected behind my firewall, I don’t want to keep them up to date. I’m way too lazy busy for that.
  • It doesn’t make a sense because I’m using Mac OS to develop but I certainly won’t run my code on this OS in production. So why bother trying to mimic a production environment when it will never be the same: different versions, different configuration, different performances, everything actually a bit different…

While I was working on Gitrepos, I had this nagging feeling that I should start testing it on a production-like environment ASAP. I was sure I was building technical debt and, guess what, I was…

Enters Vagrant

Then the other day, I went through my (very long) Pocket list and took a look at Vagrant. I mainly use Pocket as note pad/todo list and I had flagged Vagrant as something I should take a look at. It looked exactly as the best solution to solve my environment problem.

But I used VirtualBox in the past and I remember it being a PITA to setup, especially the folder sharing stuff. So I gave Vagrant a try, almost convinced it would failed. But it didn’t!

I eventually dumped Chef to use a basic shell script though:

#!/bin/sh
echo mysql-server mysql-server/root_password select "vagrant" | debconf-set-selections
echo mysql-server mysql-server/root_password_again select "vagrant" | debconf-set-selections
apt-get install -y mysql-server apache2 php5 libapache2-mod-php5 php5-mysql
VHOST=$(cat <<EOF
<VirtualHost *:80>
  DocumentRoot "/vagrant/web"
  ServerName localhost
  <Directory "/vagrant/web">
    AllowOverride All
  </Directory>
</VirtualHost>
EOF
)
echo "${VHOST}" > /etc/apache2/sites-enabled/000-default
sudo a2enmod rewrite
service apache2 restart
mysql -u root -p"vagrant" -e ";DROP DATABASE test;DROP USER ''@'localhost';CREATE DATABASE gitrepos;GRANT ALL ON gitrepos.* TO gitrepos@localhost IDENTIFIED BY 'gitrepos';GRANT ALL ON gitrepos.* TO gitrepos@'%' IDENTIFIED BY 'gitrepos'"
sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mysql/my.cnf
service mysql restart
apt-get clean

Going through this script quickly:

  • I pre-configure MySQL so apt-get runs silently and set the correct passwords
  • I create a basic virtual host file for Apache
  • I configure MySQL so I can query it from the host
  • Some cleaning

And here’s my Vagrantfile:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant::Config.run do |config|
  config.vm.box = "ubuntu_server_12_10_amd64"
  config.vm.network :hostonly, "192.168.242.2"
  config.vm.provision :shell, :path => "deploy/deploy.sh"
end

As you may have noticed I don’t use a NAT network for my VM but a “Host-Only” network so I have a fixed IP that is only accessible from the host it’s running on. That way I don’t expose my application to the outer world.

But I have 2 issues with Vagrant:

  • I’d like a provisioner that let me upload a file to the VM during setup. It’s coming soon.
  • I didn’t look hard but I’d like a repository of base boxes I can really trust.

I’m not a paranoiac but since I worked for a security company, I smell a security issue here. Gitrepos’ code is public but I wouldn’t trust a base box built by an unknown 3rd-party for private code. It’s way too easy to make one that would leak code.

So I decided to build my own Ubuntu Server 12.10 amd64 base box. Read more…

Build your own base box

Creating the VM

First, you’ll need to install Virtualbox and download the Ubuntu Server image.

In a few screenshots, here’s how to start the setup:









Installing Ubuntu

The first step of the Ubuntu installer are pretty straight forward and entirely up to you.

Then you get asked for the Hostname. Vagrant’s documentation suggests to follow a convention: vagrant-[os-name], e.g. vagrant-ubuntu-12-10-amd64 in our case.

Then for the next steps:

  • Root Password: vagrant
  • Main account login: vagrant
  • Main account password: vagrant

I don’t encrypt the disk because we don’t care in this setup. For partitioning, I use the simplest option, skipping LVM because we want to avoid unnecessary stuff that could impair performance and make the VM larger than necessary.

Let it then install stuff. I don’t enable automatic updates, it could mess up some test runs, just remember to apt-get update; apt-get upgrade once in a while. At the “software selection” step, don’t check anything, we’ll take care of that later.

Finally, install Grub with the default options and reboot.

Configuring the system

At this step, since the VM’s network uses NAT, you can’t login through SSH and copy-pasting to the VM is not possible.

Login as vagrant/vagrant. I’ve aggregated the different steps in a bash script. Just follow these steps:

cd /tmp
wget http://blog.jodet.com/uploads/vagrant.sh
chmod +x vagrant.sh
sudo ./vagrant.sh

The last step is to let the vagrant user “sudo” without having to type his password.

sudo chmod 644 /etc/sudoers
sudo vim /etc/sudoers

Add Defaults env_keep="SSH_AUTH_SOCK" to the “Defaults” and replace %admin ALL=(ALL) ALL by %admin ALL=NOPASSWD: ALL.

It should look like this: ```language-bash # # This file MUST be edited with the ‘visudo’ command as root. # # Please consider adding local content in /etc/sudoers.d/ instead of # directly modifying this file. # # See the man page for details on how to write a sudoers file. # Defaults env_reset Defaults mail_badpass Defaults secure_path=”/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin” Defaults env_keep=”SSH_AUTH_SOCK”

Host alias specification

User alias specification

Cmnd alias specification

User privilege specification

root ALL=(ALL:ALL) ALL

Members of the admin group may gain root privileges

%admin ALL=NOPASSWD: ALL

Allow members of group sudo to execute any command

%sudo ALL=(ALL:ALL) ALL

See sudoers(5) for more information on “#include” directives:

#includedir /etc/sudoers.d ```

Now you’re done, just shutdown the system with sudo shutdown -h now.

Packaging the base box

Open a terminal, go to the folder containing your VM and run:

cd VirtualBox\ VMs/ubuntu_base
vagrant package --base ubuntu_base

Your new base box is named package.box. You can now add it to your system and use it in a project like this:

vagrant box add vagrant-ubuntu-12-10-amd64 package.box
mkdir test_environment
cd test_environment
vagrant init vagrant-ubuntu-12-10-amd64
vagrant up
vagrant ssh

You can store the package.box file in a safe location and delete the VirtualBox VM if you need space.

Sources: Creating a vagrant base box for ubuntu 12.04 32bit server and the official documentation.