clock

Using Kirby with Vagrant

Following Kirby 2’s release, I spent some time adding Vagrant to my Kirby projects to make them more consistent across my various development environments. In this article, I'll go over my Vagrant setup and show you how to use it with your own Kirby projects.

For many years I struggled with using content management systems. All of my smaller personal projects never really fit into the mold of the large, feature rich, database driven applications that were available. When I discovered the wonderful NoDB CMS called Kirby, I fell in love instantly. Every design decision that was made feels like an extension of what I would have done if I had created it myself. It is truly the happiest I have ever been with a CMS.

With the release of Kirby 2, It was time to update some of my older sites and I also wanted to spend some time re-thinking my local development environment. Vagrant has been on my list for quite a while, but outside of some very small test projects I didn't have a great opportunity to dive in and really build something using it. Finally, I had the perfect opportunity to dive in and craft a simple Vagrantfile that anyone can use to quickly get a Kirby development environment running with a single command.

If you're not familiar with Vagrant, it's a fantastic tool that allows you to build a simple file of instructions that will build a development environment on a virtual machine that can be version controlled and shared amongst your entire team that ensures each member has an identical environment.

If you are already familiar with Vagrant and Kirby, then simply copying the file below may be just what you're looking for. However, if you want more detail about what the file is doing and how to use it, take a look at the code below and then afterward I will quickly break it all down and go over some basic usage to get you up and running.

The Full Vagrantfile

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

Vagrant.configure("2") do |config|

    # Box
    config.vm.box = "ubuntu/trusty64"

    # Forwarded Ports
    config.vm.network :forwarded_port, guest: 80, host: 8888

    # Shared Folders
    config.vm.synced_folder "./", "/vagrant",
        owner: "vagrant",
        group: "www-data",
        mount_options: ["dmode=775,fmode=664"]

    # Provisioning
    config.vm.provision :shell, :inline => "apt-get update --fix-missing"
    config.vm.provision :shell, :inline => "apt-get install -q -y python-software-properties python"
    config.vm.provision :shell, :inline => "add-apt-repository ppa:ondrej/php && apt-get update"
    config.vm.provision :shell, :inline => "apt-get install -q -y figlet g++ make git curl apache2 libapache2-mod-php7.0 php7.0-curl php7.0-cli php7.0-gd php7.0-mbstring"
    config.vm.provision :shell, :inline => "sed -i 's/AllowOverride None/AllowOverride All/g' /etc/apache2/apache2.conf"
    config.vm.provision :shell, :inline => "sudo a2enmod rewrite"
    config.vm.provision :shell, :inline => "sudo a2enmod expires"
    config.vm.provision :shell, :inline => "sudo a2enmod php7.0"
    config.vm.provision :shell, :inline => "service apache2 restart"

    # Change Apache Working Directory
    config.vm.provision :shell, :inline => "rm -rf /var/www/html"
    config.vm.provision :shell, :inline => "ln -fs /vagrant /var/www/html"

    # Done
    config.vm.provision :shell, :inline => "figlet SUCCESS"

end

Opening Line

We begin the file with our configuration method and pass in the version of the Vagrant configuration we will be targeting. In our case, we will be targeting version 2.0.X.

Vagrant.configure("2") do |config|

The Box

At the beginning of the file, we setup the box or virtual machine that we're going to be using. In this case, we'll be using the Ubuntu 14.04 (Trusty Tahr) 64-bit release that is provided by Hashicorp, the creators of Vagrant.

# Box
config.vm.box = "ubuntu/trusty64"

Port Forwarding

To prevent our box from conflicting with other boxes or tools, we'll need to forward all traffic to a unique port that isn't used by any other applications. In our case, we're using 8888.

# Forwarded Ports
config.vm.network :forwarded_port, guest: 80, host: 8888

This allows for us to visit http://localhost:8888 in our browser to access our website running inside of our Vagrant box.

Shared Folders & Permissions

Depending on the project, we sometimes need to specify which folders will be shared and kept in sync between the Vagrant environment and our local development machine.

Additionally, Kirby requires some additional permission settings to work properly as it will be creating, editing, and deleting files on our server instead of communicating to a database.

# Shared Folders
config.vm.synced_folder "./", "/vagrant",
    owner: "vagrant",
    group: "www-data",
    mount_options: ["dmode=775,fmode=664"]

This code notifies Vagrant that we wish to sync the root directory of our project and sets up the proper permissions so that Kirby can perform all the actions that it needs to work properly when adding, editing and deleting content.

Provisioning

Provisioning is the process in which we will automate the installation and setup of any tools that our project needs to run properly.

For example, Kirby requires that we have PHP installed alongside a web server such as Apache or NGINX. Instead of doing this manually, we can just include instructions so that Vagrant can do this for us as it builds the box. Additionally, we can make changes to configuration settings and the entire process will be automated by Vagrant.

# Provisioning
config.vm.provision :shell, :inline => "apt-get update --fix-missing"
config.vm.provision :shell, :inline => "apt-get install -q -y python-software-properties python"
config.vm.provision :shell, :inline => "add-apt-repository ppa:ondrej/php && apt-get update"
config.vm.provision :shell, :inline => "apt-get install -q -y figlet g++ make git curl apache2 libapache2-mod-php7.0 php7.0-curl php7.0-cli php7.0-gd php7.0-mbstring"
config.vm.provision :shell, :inline => "sed -i 's/AllowOverride None/AllowOverride All/g' /etc/apache2/apache2.conf"
config.vm.provision :shell, :inline => "sudo a2enmod rewrite"
config.vm.provision :shell, :inline => "sudo a2enmod expires"
config.vm.provision :shell, :inline => "sudo a2enmod php7.0"
config.vm.provision :shell, :inline => "service apache2 restart"

In the provisioning above, we've updated our package lists to ensure that apt-get has the latest package information before we perform any installations. Next, we install all of our dependencies and modify the Apache config so we can use our .htaccess file to add rewrite rules along with other options.

This stack of applications is my most common set of tools that I use to get the most out of my Kirby projects, but you may need additional tools depending on your project! Use this to get your Vagrant build started and then add in tools as they are needed.

It is worth noting that you can alternatively store all of your provisioning in an external file and just reference it. I've only inlined my provisioning because I personally prefer only having to maintain a single file.

# Local Provisioning File
config.vm.provision "shell", path: "script.sh"

Additionally, if you wish to create a shared provisioning file, you can also plug in a URL in place of the file path. I've considered moving to this method!

# Hosted Provisioning File
config.vm.provision "shell", path: "https://example.com/script.sh"

Finally, just for fun, we wrap things up by announcing our success using figlet.

# Announce Success
config.vm.provision :shell, :inline => "figlet SUCCESS"

Usage

This file is great and all, but if you've never used Vagrant before, I'm sure it can still be pretty intimidating. However, you will be pleasantly surprised at how easy it is to implement into your project. Once Vagrant has been installed, you simply need to save the code above in a file named Vagrantfile (with no file extension) in the root directory of your project.

Once it has been created, the next step is to navigate into your project directory via the command-line and run the vagrant up command which will begin building the box we just configured. Once the build process has completed, you can open up your favorite browser and navigate to http://localhost:8888 to view your project.

If you run into any trouble or have improvements, be sure to let me know in the comments. If you have not yet used Kirby, be sure to give it a try! I've also included some additional resources for learning more about Kirby and Vagrant in the section below. Enjoy!

Additional Resources