Re-introducing Vagrant: The Right Way to Start with PHP
I often get asked to recommend beginner resources for people new to PHP. And, it’s true, we don’t have many truly newbie friendly ones. I’d like to change that by first talking about the basics of environment configuration. In this post, you’ll learn about the very first thing you should do before starting to work with PHP (or any other language, for that matter).
We’ll be re-introducing Vagrant powered development.
Note that this topic (among other best practices) is covered in much more depth in SitePoint’s Jump Start PHP Environment Book.
Please take the time to read through the entire article – I realize it’s a wall of text, but it’s an important wall of text. By following the advice within, you’ll be doing not only yourself one hell of a favor, but you’ll be benefitting countless other developers in the future as well. The post will be mainly theory, but in the end we’ll link to a quick 5-minute tutorial designed to get you up and running with Vagrant in almost no time. It’s recommended you absorb the theory behind it before you do that, though.
Just in case you’d like to rush ahead and get something tangible up and running before getting into theory, here’s the link to that tutorial.
Let’s start with the obvious question – what is Vagrant? To explain this, we need to explain the following 3 terms first:
- Virtual Machine
In definitions as simple as I can conjure them, a Virtual Machine (VM) is an isolated part of your main computer which thinks it’s a computer on its own. For example, if you have a CPU with 4 cores, 12 GB of RAM and 500 GB of hard drive space, you could turn 1 core, 4 GB or RAM and 20GB or hard drive space into a VM. That VM then thinks it’s a computer with that many resources, and is completely unaware of its “parent” system – it thinks it’s a computer in its own right. That allows you to have a “computer within a computer” (yes, even a new “monitor”, which is essentially a window inside a window – see image below):
A Windows VM inside a Mac OS X system
This has several advantages:
- you can mess up anything you want, and nothing breaks on your main machine. Imagine accidentally downloading a virus – on your main machine, that could be catastrophic. Your entire computer would be at risk. But if you downloaded a virus inside a VM, only the VM is at risk because it has no real connection to the parent system it lives off of. Thus, the VM, when infected, can simply be destroyed and re-configured back into existence, clean as a whistle, no consequences.
- you can test out applications for other operating systems. For example, you have an Apple computer, but you really want that one specific Windows application that Apple doesn’t have. Just power up a Windows VM, and run the application inside it (like in the image above)!
- you keep your main OS free of junk. By installing stuff onto your virtual machine, you avoid having to install anything on your main machine (the one on which the VM is running), keeping the main OS clean, fast, and as close to its “brand new” state as possible for a long time.
You might wonder – if I dedicate that much of my host computer to the VM (an entire CPU core, 4GB of RAM, etc), won’t that:
- make my main computer slower?
- make the VM slow, because that’s kind of a weak machine?
The answer to both is “yes” – but here’s why this isn’t a big deal. You only run the VM when you need it – when you don’t, you “power it down”, which is just like shutting down a physical computer. The resources (your CPU core, etc.) are then instantly freed up. The VM being slow is not a problem because it’s not meant to be a main machine – you have the host for that, your main computer. So the VM is there only for a specific purpose, and for that purpose, those resources are far more than enough. If you really need a VM more powerful than the host OS, then just give the VM more resources – like if you want to play a powerful game on your Windows machine and you’re on a Mac computer with 4 CPU cores, give the VM 3 cores and 70-80% of your RAM – the VM instantly becomes powerful enough to run your game!
But, how do you “make” a virtual machine? This is where software like VirtualBox comes in.
VirtualBox is a program which lets you quickly and easily create virtual machines. An alternative to VirtualBox is VMware. You can (and should immediately) install VirtualBox here.
VirtualBox provides an easy to use graphical interface for configuring new virtual machines. It’ll let you select the number of CPU cores, disk space, and more. To use it, you need an existing image (an installation CD, for example) of the operating system you want running on the VM you’re building. For example, if you want a Windows VM as in the image above, you’ll need a Windows installation DVD handy. Same for the different flavors of Linux, OS X, and so on.
When a new VM is created, it’s bare-bones. It contains nothing but the installed operating system – no additional applications, no drivers, nothing. You still need to configure it as if it were a brand new computer you just bought. This takes a lot of time, and people came up with different ways around it. One such way is provisioning, or the act of using a pre-written script to install everything for you.
With a provisioning process, you only need to create a new VM and launch the provisioner (a provisioner is a special program that takes special instructions) and everything will be taken care of automatically for you. Some popular provisioners are: Ansible, Chef, Puppet, etc – each has a special syntax in the configuration “recipe” that you need to learn. But have no fear – this, too, can be skipped. Keep reading.
This is where we get to Vagrant. Vagrant is another program that combines the powers of a provisioner and VirtualBox to configure a VM for you.
You can (and should immediately) install Vagrant here.
Vagrant, however, takes a different approach to VMs. Where traditional VMs have a graphical user interface (GUI) with windows, folders and whatnot, thus taking a long time to boot up and become usable once configured, Vagrant-powered VMs don’t. Vagrant strips out the stuff you don’t need because it’s development oriented, meaning it helps with the creation of development friendly VMs.
Vagrant machines will have no graphical elements, no windows, no taskbars, nothing to use a mouse on. They are used exclusively through the terminal (or command line on Windows – but for the sake of simplicity, I’ll refer to it as the terminal from now on). This has several advantages over standard VMs:
- Vagrant VMs are brutally fast to boot up. It takes literally seconds to turn on a VM and start developing on it. Look how quickly it happens for me – 25 seconds flat from start to finish:
- Vagrant VMs are brutally fast to use – with no graphical elements to take up valuable CPU cycles and RAM, the VM is as fast as a regular computer
- Vagrant VMs resemble real servers. If you know how to use a Vagrant VM, you’re well on your way to being able to find your way around a real server, too.
- Vagrant VMs are very light due to their stripped out nature, so their configuration can typically be much weaker than that of regular, graphics-powered VMs. A single CPU core and 1GB of RAM is more than enough in the vast majority of use cases when developing with PHP. That means you can not only boot up a Vagrant VM on a very weak computer, you can also boot up several and still not have to worry about running out of resources.
- Perhaps most importantly, Vagrant VMs are destructible. If something goes wrong on your VM – you install something malicious, you remove something essential by accident, or any other calamity occurs, all you need to do to get back to the original state is run two commands:
vagrant destroywhich will destroy the VM and everything that was installed on it after the provisioning process (which happens right after booting up), and
vagrant upwhich rebuilds it from scratch and re-runs the provisioning process afterwards, effectively turning back time to before you messed things up.
With Vagrant, you have a highly forgiving environment that can restore everything to its original state in minutes, saving you hours upon hours of debugging and reinstallation procedures.
So, why do this for PHP development in particular?
- The ability to test on several versions of PHP, or PHP with different extensions installed. One VM can be running PHP 5.5, one can be running PHP 5.6, one can be running PHP 7. Test your code on each – no need to reinstall anything. Instantly be sure your code is cross-version compatible.
- The ability to test on several servers. Test on Apache in one VM, test on Nginx in another, or on Lighttpd on yet another – same thing as above: make sure your code works on all server configurations.
- Benchmark your code’s execution speed on different combinations of servers + PHP versions. Maybe the code will execute twice as fast on Nginx + PHP 7, allowing you to optimize further and alert potential users to possible speed gains.
- Share the same environment with other team members, avoiding the “it works on my machine” excuses. All it takes is sharing a single Vagrantfile (which contains all of the necessary configuration) and everyone has the exact same setup as you do.
- Get dev/prod parity: configure your Vagrant VM to use the same software (and versions) as your production (live) server. For example, if you have Nginx and PHP 5.6.11 running on the live server, set the Vagrant VM up in the exact same way. That way, you’re 100% certain your code will instantly work when you deploy it to production, meaning no downtime for your visitors!
These are the main but not the only reasons.
But why not XAMPP? XAMPP is a pre-built package of PHP, Apache, MySQL (and Perl, for the three people in the world who need it) that makes a working PHP environment just one click away. Surely this is better than Vagrant, no? I mean, a single click versus learning about terminal, Git cloning, virtual machines, hosts, etc…? Well actually, it’s much worse, for the following reasons:
- With XAMPP, you absorb zero server-config know-how, staying 100% clueless about terminal, manual software installations, SSH usage, and everything else you’ll one day desperately need to deploy a real application.
- With XAMPP, you’re never on the most recent version of the software. It being a pre-configured stack of software, updating an individual part takes time and effort so it’s usually not done unless a major version change is involved. As such, you’re always operating on something at least a little bit outdated.
- XAMPP forces you to use Apache. Not that Nginx is the alpha and omega of server software, but being able to at least test on it would be highly beneficial. With XAMPP and similar packages, you have no option to do this.
- XAMPP forces you to use MySQL. Same as above, being able to switch databases at will is a great perk of VM-based development, because it lets you not only learn new technologies, but also use those that fit the use case. For example, you won’t be building a social network with MySQL – you’ll use a graph database – but with packages like XAMPP, you can kiss that option goodbye unless you get into additional shenanigans of installing it on your machine, which brings along a host of new problems.
- XAMPP installs on your host OS, meaning it pollutes your main system’s space. Every time your computer boots up, it’ll be a little bit slower because of this because the software will load whether or not you’re planning to do some development that day. With VMs, you only power them on when you need them.
- XAMPP is version locked – you can’t switch out a version of PHP for another, or a version of MySQL for another. All you can do is use what you’re given, and while this may be fine for someone who is 100% new to PHP, it’s harmful in the long run because it gives a false sense of safety and certainty.
- XAMPP is OS-specific. If you use Windows and install XAMPP, you have to put up with the various problems PHP has on Windows. Code that works on Windows might not work on Linux, and vice versa. Since the vast, vast majority of PHP sites are running on Linux servers, developing on a Linux VM (powered by Vagrant) makes sense.
There are many more reasons not to use XAMPP (and similar packages like MAMP, WAMP, etc), but these are the main ones.
So how does one power up a Vagrant box?
The first way, which involves a bit of experimentation and downloading of copious amounts of data is going to Hashicorp’s Vagrant Box list here, finding one you like, and executing the command you can find in the box’s details. For example, to power up a 64bit Ubuntu 14.04 VM, you run:
vagrant init ubuntu/trusty64 in a folder of your choice after you installed Vagrant, as per instructions. This will download the box into your local Vagrant copy, keeping it for future use (you only have to download once) so future VMs based off of this one are set up faster.
Note that the Hashicorp (which, by the way, is the company behind Vagrant) boxes don’t have to be bare-bones VMs. Some come with software pre-installed, making everything that much faster. For example, the laravel/homestead box comes with the newest PHP, MySQL, Nginx, PostgreSQL, etc pre-installed, so you can get to work almost immediately (more on that in the next section).
Another way is grabbing someone’s pre-configured Vagrant box from Github. The boxes from the list in the link above are decent enough but don’t have everything you might want installed or configured. For example, the homestead box does come with PHP and Nginx, but if you boot it up you won’t have a server configured, and you won’t be able to visit your site in a browser. To get this, you need a provisioner, and that’s where Vagrantfiles come into play. When you fetch someone’s Vagrantfile off of Github, you get the configuration, too – everything gets set up for you. That brings us into HI.
HI (short for Homestead Improved) is a version of laravel/homestead. We use this box at SitePoint extensively to bootstrap new projects and tutorials quickly, so that all readers have the same development environment to work with. Why a version and not the original homestead you may wonder? Because the original requires you to have PHP installed on your host machine (the one on which you’ll boot up your VM) and I’m a big supporter of cross-platform development in that you don’t need to change anything on your host OS when switching machines. By using Homestead Improved, you get an environment ready for absolutely any operating system with almost zero effort.
The gif above where I boot up a VM in 25 seconds – that’s a HI VM, one I use for a specific project.
I recommend you go through this quick tip to get it up and running quickly. The first run might take a little longer, due to the box having to download, but subsequent runs should be as fast as the one in my gif above.
Please do this now – if at any point you get stuck, please let me know and I’ll come running to help you out; I really want everyone to transition to Vagrant-driven-development as soon as possible.
By using HI (and Vagrant in general), you’re paving the way for your own cross-platform development experience and keeping your host OS clean and isolated from all your development efforts.
Below you’ll find a list of other useful resources to supercharge your new Vagrant powers:
- SitePoint Vagrant posts many tutorials on lots of different aspects of developing with Vagrant, some explaining the links below, some going beyond that and diving into manually provisioning a box or even creating your own, and so on.
- StackOverflow Vagrant Tag for questions and answers about Vagrant, if you run into problems setting it up
- PuPHPet – a way to graphically configure the provisioning of a new Vagrant box to your needs – select a server, a version of PHP, a database, and much more. Uses the Puppet provisioner. Knowledge of Puppet not required.
- Phansible – same as PuPHPet but uses the Ansible provisioner. Knowledge of Ansible not required.
- Vaprobash a set of Bash scripts you can download (no provisioner – raw terminal commands in various files that just get executed) as an alternative to the above two. Requires a bit more manual work, but usually results in less bloated VMs due to finetuneability.
- 5 ways to get started with Vagrant – lists the above resources, plus some others.
Do you have any questions? Is anything unclear? Would you like me to go into more depth with any of the topics mentioned above? Please let me know in the comments below, and I’ll do my best to clear things up.