Does creating and managing development environments frustrate you, slow you down, or distract you from development? Do you have issues because your development and deployed environments differ? If so, I've got the solution for you – PuPHPet!
I can't speak for you, but one of my pet peeves about software development is environments. Whether it's creating and maintaining them for different projects with different needs; ensuring environment parity across a development team, (especially when they're remote); or between environments such as development, testing, and production. Across all of these, it can be a laborious task, especially when done manually.
As we all know, the amount of options, the variety of choice, the demands of the IT manager, team lead, or client can be stressful. They can (and do) pull us in a multitude of directions, oftentimes simultaneously.
There's database choices such as MySQL, PostgreSQL, Oracle and SQLServer. There's NoSQL choices such as Cassandra, Hadoop, and Redis. There's webserver choices such as Apache and Nginx. The list goes on and on.
And when we don't have a dedicated sys admin team (say we're a solo freelancer or in a very small team), time taken to maintain development environments becomes really precious – we become DEVOPS.
In pursuit of ending this pain and making the entire process as efficient as possible, I set about the task of learning Vagrant & Puppet. From discussions with colleagues and internet research, these two tools seem to be the standard for creating reusable environments. If you're not familiar with these excellent tools, here are two short excerpts from their respective manuals:
Create and configure lightweight, reproducible, and portable development environments. Vagrant will change how you work
Puppet is IT automation software that helps system administrators manage infrastructure throughout its lifecycle, from provisioning and configuration to orchestration and reporting. Using Puppet, you can easily automate repetitive tasks, quickly deploy critical applications, and proactively manage change, scaling from 10s of servers to 1000s, on-premise or in the cloud.
However, like most people in the modern world, I'm impatient. Like you, I have a lot going on, plus I was not seeking to become a guru. I felt there must be a way to come up to speed quickly but without becoming an aficionado.
After some further googling, I came across the subject of this article, PuPHPet, an excellent GUI tool providing a simple wizard, which creates a Puppet-powered Vagrant configuration, usable immediately.
It focuses on 5 areas:
- Deploy Target (memory, ip address, port forwarding)
- Server Basics
- PHP (modules, libraries, config settings)
- Database (PostgreSQL, MySQL)
- Webserver (Apache 2, Nginx)
Whether you want to have PHP 5.5 running PostgreSQL and Nginx or PHP 5.4 running Apache 2 and MySQL, you can rapidly create and download the configuration, getting going in minutes.
Admittedly, there's a lot more to an environment than these choices; but, to be fair, it's early days and what it already provides, it does really well.
With PuPHPet, you'll be up and running inside a half hour, and all you have to do is run:
That's right. In the uncompressed PuPHPet archive, you need only run that command, wait a bit, and you're ready to go. Don't believe me? Let's step through the process from start to finish together.
After we're done, I wholeheartedly encourage you to play to your hearts content, changing options, adding removing packages and more and see what you find. I'm confident you'll be impressed.
A word of warning before we start. One of the biggest problems I faced when I first started was having the right versions of both Vagrant and VirtualBox. It appeared as though I'd only get part way and have to do the rest manually. It was never clear what had gone wrong or how complete the process was.
Firstly, install a copy of these two packages.
Creating the Configuration
With them installed, open up https://puphpet.com. You can see, right at the top, that there are four initial choices: Local, Digital Ocean, Rackspace and Amazon Web Services. Choose Local as we're not using these online services in this tutorial.
Under "Local VM Details", we can specify the VM's:
– Operating System
– IP Address
– Memory Allocation
For today's example, we're using Debian Wheezy 7.2 x64 with VirtualBox 4.3. This allows us to use PHP 5.5 or 5.4. Feel free to leave the remaining three settings as they are, or adjust as suits you best.
Next comes Local VM Forwarded Ports. I've not configured it, but if you want to setup some ports on your host machine to forward to ports on the guest VM, then configure them here, as necessary.
Sharing Folders with Local VM
Here we begin to see the power and flexibility that Vagrant and Puppet provide. In Box Sync Folder Source you specify a local directory which will map to a directory on the guest VM at the location specified by Box Sync Folder Target. I've left the defaults for both of these and also for Shared Folder Type.
This option is handy if you want to set up a number of custom directories on your VM. Say you have an existing working copy under
~/Documents/workspace/your-project. You could map this to a directory directly in the web root of your VM's web server. That way you can develop locally, with no syncing or copying requirements to the virtual machine.
If there are specific packages that you need available, such as git, subversion, vim, etc, then list them here. One thing to remember, is you need to know the package name as specified in your chosen operating system. No list is provided in the popup when you type.
Apache(2) or Nginx? For this tutorial, I'm going with Apache. The configuration choices are simple and straight-forward. First specify the modules to be installed and enabled by typing in the Apache Modules field. This will popup a list of available options for you to choose from – helping ensure an error free process.
Next comes the Virtual Host configuration. What is the server name and alias of your application? First specify them, then the root directory and port. What we'll do is set the same directory for the Document Root as we specified in Box Sync Folder Target, to keep things nice and simple. Unless you have a specific need, leave the port at the default 80.
The final two settings, Environment Variables and AllowOverride, only change if your application needs it. For today, the defaults are fine.
Only a few options are available here, but they're good enough for what we need. I've left the default of PHP 5.5 (why would you want anything else?). I've also left Composer selected. If you've not used Composer, or are not sure what all the fuss is about, read this excellent post by Ben Ramsey, or this post on Composer here on SitePoint.
Under INI Settings, I've accepted the defaults and then added in allow_url_fopen, allow_url_include, error_log, file_uploads, and apc.enabled. Feel free to do the same, or browse and choose from the extensive list.
I've changed my PHP Timezone to Europe/Berlin as that's the closest to me. But change yours as best suits your location. For PHP Modules, my list is cli, intl, mcrypt, cgi, curl, memcached, memcache, pspell, tidy and sqlite. Scroll through the list and add the ones that you need (or would like). For PEAR and Pecl modules, I've left these as they were.
I've elected to install Xdebug, taking the default settings, but not Xhprof. XDebug is just excellent, so I highly recommend you use it.
Ok, we're getting serious now. For today's example, I've chosen MySQL, setting the root password to password and left privileges at all. The DB name is sitepoint, the username is testuser and the password, testpassword. I've kept the choices here simple, so as not to overcomplicate the situation. I don't have a SQL script to run on VM load, so have left this blank.
Create & Download the Config
Now, just click the extremely large button Go ahead then, make it. You'll see the download appear in your downloads directory. After it's finished, extract the archive and cd into the directory in your terminal. From there, run
This begins the process of building the VM. If you've not downloaded a Box file yet or don't have one matching the operating system you've specified, you'll have to wait a bit longer as it's downloaded, before the VM can be built. All being well, you'll see output like the following:
✗ vagrant up Bringing machine 'default' up with 'virtualbox' provider... [default] Importing base box 'debian-wheezy72-x64-vbox43'... [default] Matching MAC address for NAT networking... [default] Setting the name of the VM... [default] Clearing any previously set forwarded ports... [default] Creating shared folders metadata... [default] Clearing any previously set network interfaces... [default] Preparing network interfaces based on configuration... [default] Forwarding ports... [default] -- 22 => 2222 (adapter 1) [default] Running 'pre-boot' VM customizations... [default] Booting VM... [default] Waiting for machine to boot. This may take a few minutes... [default] Machine booted and ready! [default] Configuring and enabling network interfaces... [default] Mounting shared folders... [default] -- /vagrant [default] -- /var/www [default] -- /tmp/vagrant-puppet/manifests [default] Running provisioner: shell... [default] Running: /var/folders/_w/k6fxbl615w700lgkrtt0vb3w0000gn/T/vagrant-shell20131126-3538-kid3ga stdin: is not a tty ____ ____ _ _ ____ _ generated using | _ \ _ _| _ \| | | | _ \ ___| |_ ___ ___ _ __ ___ | |_) | | | | |_) | |_| | |_) / _ \ __| / __/ _ \| '_ ` _ \ | __/| |_| | __/| _ | __/ __/ |_ | (_| (_) | | | | | | |_| \__,_|_| |_| |_|_| \___|\__(_)___\___/|_| |_| |_| Created directory /.puphpet-stuff Running initial-setup apt-get update Finished running initial-setup apt-get update [default] Running provisioner: shell... [default] Running: /var/folders/_w/k6fxbl615w700lgkrtt0vb3w0000gn/T/vagrant-shell20131126-3538-1116fzj stdin: is not a tty Downloading http://apt.puppetlabs.com/puppetlabs-release-wheezy.deb Finished downloading http://apt.puppetlabs.com/puppetlabs-release-wheezy.deb Running update-puppet apt-get update Finished running update-puppet apt-get update Updating Puppet to latest version dpkg-preconfigure: unable to re-open stdin: No such file or directory Finished updating puppet to latest version: Puppet v3.3.2 Created empty file /.puphpet-stuff/update-puppet ... Info: Creating state file /var/lib/puppet/state/state.yaml Notice: Finished catalog run in 436.21 seconds
This indicates that everything has gone well.
Check Everything's Working
Now that the Virtual Machine's built, login and check it out. To do that, from the same directory, run
vagrant ssh. Once you're in, to quickly validate all's ok, run
sudo netstat -tlnp. This shows what services are running. It should give you output matching the following
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1643/rpcbind tcp 0 0 0.0.0.0:39284 0.0.0.0:* LISTEN 1678/rpc.statd tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2643/sshd tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 13637/postgres tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2399/exim4 tcp6 0 0 :::111 :::* LISTEN 1643/rpcbind tcp6 0 0 :::80 :::* LISTEN 31623/apache2 tcp6 0 0 :::22 :::* LISTEN 2643/sshd tcp6 0 0 ::1:5432 :::* LISTEN 13637/postgres tcp6 0 0 ::1:25 :::* LISTEN 2399/exim4 tcp6 0 0 :::37887 :::* LISTEN 1678/rpc.statd
There you see that Apache and PostgreSQL are running. If you look under
/etc/apache2/sites-enabled/ you'll see a configuration for your virtual host, using a pseudo-random name. If you've added the hostname to
/etc/hosts on your local machine, then you can open up the hostname in your browser and view the page that results.
So there you have it. Ok, the first time through, like anything, it might seem like a lot of steps to perform. But as you become more familiar, you'll get a lot faster. What's more, you don't need to recreate from scratch every time.
If you drag
puppet/hieradata/common.yaml onto puphpet.com, it will automatically fill out the form to match the configuration contained. Then just adjust to match you needs. So once you've done the first one, subsequent ones are much quicker and easier.
What do you think? Are you keen to use it, and leave the days of building Virtual Machines by hand behind? Share your thoughts in the comments.
Matthew Setter is a software developer, specialising in reliable, tested, and secure PHP code. He’s also the author of Mezzio Essentials (https://mezzioessentials.com) a comprehensive introduction to developing applications with PHP's Mezzio Framework.