Friday, September 26, 2014

A happy developer's environment: part 1

I have been working lately with my development stack held inside a linux container (LXC), and it has been my best sandboxing experience so far, so I decided to share the process with everyone.

In this first part I will cover the vagrant and lxc installation and the box creation, later in part 2 I will cover provision and backup of the box.

Install lxc

sudo apt-get install lxc

Install Vagrant

Go to and download and install the appropiate one for you

Install Vagrant-LXC plugin

vagrant plgin install  vagrant-lxc

Clone Vagrant-LXC-boxes repo

git clone

Build a base box with your provisioner of choice

CHEF=1 make precise
==> [ubuntu-precise] Building box to 'output/2014-09-26/'...
    [ubuntu-precise] Creating container...
    [ubuntu-precise] Container created!
    [ubuntu-precise] Adding ipv6 allhosts entry to container's /etc/hosts
    [ubuntu-precise] Running [/usr/sbin/locale-gen es_ES.UTF-8] inside 'vagrant-base-precise-amd64' container...
    [ubuntu-precise] Running [update-locale LANG=es_ES.UTF-8] inside 'vagrant-base-precise-amd64' container...
==> [ubuntu-precise] Installing extra packages and upgrading
    [ubuntu-precise] Sleeping for 5 seconds...
    [ubuntu-precise] Running [apt-get update] inside 'vagrant-base-precise-amd64' container...
    [ubuntu-precise] Running [apt-get install vim software-properties-common nfs-common curl wget man-db bash-completion python-software-properties ca-certificates sudo -y --force-yes] inside 'vagrant-base-precise-amd64' container...
    [ubuntu-precise] Running [apt-get upgrade -y --force-yes] inside 'vagrant-base-precise-amd64' container...
    [ubuntu-precise] Installing Chef
    [ubuntu-precise] Running [/tmp/] inside 'vagrant-base-precise-amd64' container...
    [ubuntu-precise] Skipping Puppet installation
    [ubuntu-precise] Skipping Salt installation
    [ubuntu-precise] Skipping Babushka installation
==> [ubuntu-precise] Preparing vagrant user...
    [ubuntu-precise] Renamed ubuntu user to vagrant and changed password.
    [ubuntu-precise] SSH credentials configured for the vagrant user.
    [ubuntu-precise] Sudoers file created.
==> [ubuntu-precise] Cleaning up 'vagrant-base-precise-amd64'...
    [ubuntu-precise] Removing temporary files...
    [ubuntu-precise] cleaning up dhcp leases
    [ubuntu-precise] Removing downloaded packages...
    [ubuntu-precise] Running [apt-get clean] inside 'vagrant-base-precise-amd64' container...
==> [ubuntu-precise] Packaging 'vagrant-base-precise-amd64' to 'output/2014-09-26/'...
    [ubuntu-precise] Removing previous rootfs tarball
    [ubuntu-precise] Compressing container's rootfs
    [ubuntu-precise] Preparing box package contents
    [ubuntu-precise] Packaging box
==> [ubuntu-precise] Finished building 'output/2014-09-26/'!
    [ubuntu-precise] Run `sudo lxc-destroy -n vagrant-base-precise-amd64` or `make clean` to remove the container that was created along the way

Move/rename box

mv output/2014-09-26/ ../

Remove build artifacts

make clean
cd ..

Create a Vagrantfile


Vagrant.configure("2") do |config| = "precise64"
  config.vm.box_url = "./"
  config.vm.provider :lxc do |lxc|
    # Same effect as 'customize ["modifyvm", :id, "--memory", "1024"]' for VirtualBox
    # lxc.customize 'cgroup.memory.limit_in_bytes', '1024M'

Set up NFS folder sync (if you want)

On the server:

Add to the Vagrantfile:
config.vm.synced_folder './code', '/home/vagrant/code', nfs: true

As root add in /etc/apparmor.d/lxc/lxc-default:
profile lxc-container-default flags=(attach_disconnected,mediate_deleted) {
    mount options=(rw, bind),
Reload apparmor:
sudo /etc/init.d/apparmor reload

Launch Vagrant (it will import the .box the first time)

vagrant up
Bringing machine 'default' up with 'lxc' provider...
==> default: Setting up mount entries for shared folders...
    default: /vagrant => /tmp/lxc
==> default: Starting container...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address:
    default: SSH username: vagrant
    default: SSH auth method: private key
==> default: Machine booted and ready!
==> default: Exporting NFS shared folders...
==> default: Preparing to edit /etc/exports. Administrator privileges will be required...
nfsd running
==> default: Mounting NFS shared folders...
==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> default: to force provisioning. Provisioners marked to run always will still run.
If you get tired of writing your password:
vagrant lxc sudoers

Access the machine

vagrant ssh
Welcome to Ubuntu 12.04.5 LTS (GNU/Linux 3.13.0-35-generic x86_64)

 * Documentation:
And that's all, you are in, if you just wanted to have an isolated environment to make experiments without paying for servers or loosing performance like virtual machines, then you are good to go.

Otherwise, if you are still interested in the provisioning thing keep tuned for the second part.