Creating a Custom Vagrant Box

Published on , in Tooling with no comments .

If you are a new Vagrant user then you should read about Vagrant and use existing base boxes to get you started. Creating your own base box isn’t recommended for a new user.

For this tutorial I’ll be creating a base box for Ubuntu Server 13.10 (64bit) running on VirtualBox 4.3.6. Vagrant is at version 1.4.1 at the time of this post. If you’re using another provider or installing a different OS then the commands and steps shown may not apply but the process is still the same.

Create the Virtual Machine

To begin, we have to configure a new VM in VirtualBox.

  • Name: vagrant-{distro}-{version}
  • Type: Linux
  • Version: {distro} (64bit)
  • Memory: 385MB
  • CPU: 2
  • Virtual Disk
    • VMDK (Dynamic)
    • Size: 40GB
  • Disable Audio
  • Disable USB
  • Set Network Adapter 1 to NAT with Port Forwarding
    • Name: SSH
    • Protocol: TCP
    • Host Port: 2222
    • Guest Port: 22

Since this will be a base box there’s no need to allocate lots of resources since this can be overridden in the Vagrantfile on a per project basis like so.

config.vm.provider "virtualbox" do |v|
	v.memory = 1024
	v.customize [
		"modifyvm", :id,
		"--cpus", 4,
		"--pae", "on",

Consult the VirtualBox Manual for more information on what settings you can override.

Installing the OS

Now that the VM has been configured we can boot the machine and mount the ISO to begin the installation. Complete the installation but use the following when prompted:

  • Host Name: vagrant-{distro}-{version}
  • Root Password*: vagrant
  • New User Full Name: vagrant
  • Username: vagrant
  • Password: vagrant

* Ubuntu doesn’t normally ask for a root password but that doesn’t matter. If it, or the OS you are installing, does then set it to “vagrant.”

Configuring the OS

Since this is a base box you should install and configure only what is absolutely necessary as additional packages and configuration can be achieved when provisioning the box on a per project basis. This helps keep the base box as lean as possible.

Change the Default Editor

Firstly, I like to change the default editor. On Ubuntu this is Nano but I’m used to vim.

$ sudo update-alternatives --config editor

Modify the Sudoers File

$ sudo su -
$ visudo
# Add the following line to the end of the file.

This means that the vagrant user should now be able to use sudo without having to enter a password each time.

Update Installed Packages

$ sudo apt-get update -y
$ sudo apt-get upgrade -y
# Restart the machine
$ sudo shutdown -r now

This will ensure all installed packages are up to date and then it will restart the machine.

Install Vagrant Public Keys

To SSH into the box we need to add the Vagrant public keys. This means we don’t have to enter a password to login.

$ mkdir -p /home/vagrant/.ssh
$ wget --no-check-certificate -O /home/vagrant/.ssh/authorized_keys
# Ensure we have the correct permissions set
$ chmod 0700 /home/vagrant/.ssh
$ chmod 0600 /home/vagrant/.ssh/authorized_keys
$ chown -R vagrant /home/vagrant/.ssh

Install OpenSSH Server

$ sudo apt-get install -y openssh-server
$ sudo vi /etc/ssh/sshd_config

Ensure the following is set.

  • Port 22
  • PubKeyAuthentication yes
  • AuthorizedKeysFile %h/.ssh/authorized_keys
  • PermitEmptyPasswords no

Save & close the file then restart SSH.

$ sudo service ssh restart

Install Guest Additions

Guest Additions is required so shared folders work.

$ sudo apt-get install -y build-essential linux-headers-server
# Mount guest additions ISO via virtualbox window
$ sudo mount /dev/cdrom /media/cdrom
$ sudo /media/cdrom/
$ sudo umount /media/cdrom
$ sudo apt-get clean

Change the GRUB Timer

We need to change the GRUB config so it doesn’t hang on the boot screen which can sometimes happen.

Make sure that GRUB_TIMEOUT is set to “1”, GRUB_HIDDEN_TIMEOUT_QUIET is set to “true”, and GRUB_CMDLINE_LINUX_DEFAULT is set tp “quiet.” Save & close the file then update GRUB.

$ sudo vi /etc/default/grub
$ sudo update-grub

Packaging the Box

These commands can greatly reduce the size of the final box we will produce. It helped reduce one of my test boxes from around 750MB to around 420MB. It will take a minute or two to run but it’s definitely worth it. To save additional space you could also remove any pre-installed packages that you think are un-necessary before running this step. Remember that anything you remove can easily be re-installed with provisioners when using the box.

$ sudo dd if=/dev/zero of=/EMPTY bs=1M
$ sudo rm -f /EMPTY
# Shutdown the machine
$ sudo shutdown -h now

The next command will actually create our box. The directory where you run this command is where the box file will be created.

$ vagrant package –-base vagrant-{distro}-{version}

Testing the Box

If everything went well you should be able to initialise a new VM using the box you just created. You should also be able to SSH into the machine. You can be as careless as you like since you can easily re-create the machine by running vagrant up again after vagrant destroy.

$ vagrant box add {boxname}
$ vagrant init {boxname}
$ vagrant up


I’ve created a new post on how I manage my Vagrant set-up which you may find useful.

Leave a Comment