By Matthew Setter

Build Virtual Machines Easily With PuPHPet

By Matthew Setter

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.

Enter PuPHPet

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.

Originally started a few short months ago by Juan Treminio, PuPHPet makes creating environments perfectly tailored for PHP developers on stacks such as {W,M,L}AMP dead simple.

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:

vagrant up

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.

Required Software

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.

So if you're finding things aren't working, try different versions of both packages. I'm currently running Vagrant 1.3.5 and VirtualBox 4.3.2 and they've worked flawlessly every time.

Firstly, install a copy of these two packages.


Creating the Configuration

With them installed, open up 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
– Hostname
– 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.

Server Basics

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 vagrant up.

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
Finished downloading
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   *               LISTEN      1643/rpcbind    
tcp        0      0 *               LISTEN      1678/rpc.statd  
tcp        0      0    *               LISTEN      2643/sshd       
tcp        0      0*               LISTEN      13637/postgres  
tcp        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.

We're Done!

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, 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.

  • nice post !

  • Etienne

    This could be a great help… but I don’t know, normally I have a virtualbox that I like so I always clone it, a lots easier and everything is always like I want.

    • Hi Etienne, so did I for quite some time. I’ve played with VirtualBox, VMWare Fusion, and Parallels. But the hassle of maintaining it in a simple way was frustrating. After I started using PuPHPet the time required just dropped, so I’ve all but stopped manually doing everything now.

  • Guilherme Akio Sakae

    Vagrant is awsone, there are many messy repos in github that you get lost, nice tool for beginners

    • @guilhermeakiosakae:disqus – sure is. As I said, I’m no expert, but am actively learning. Vagrant’s rapidly become a standard part of my repos now so that there should be no issues of it working or not working for another developer. What are your Vagrant tips?

      • Guilherme Akio Sakae

        I’m not an expert either, in one of my projects with virtualenv (python/Django) apparently vagrant get’s very slow with a big number of files in shared folder. In my case the env with python libs have a lot, really a lot, of files and this affects the overall performance. The solution is to put the libs in a not shared folder. In general the tool (puphpet) cover well the minor annoyances I had in the past, like naming the machines so they wont get lost in virtualbox.

        • Sounds like we’re learning together. :-) It sounds strange, on the surface of it, that Vagrant would get slow with a lot of files. I would have thought that would be an issue with the guest VM. I’m really intrigued and will do more reading about it.

          • Guilherme Akio Sakae

            Oh I forgot to mention, only happens in ubuntu OS , I’m not tried in windows but in my mac everything goes fine, maybe something related to NFS option in shared folder type. Here’s a issue in vagrant’s github I don’t know if still happens but is good to know.

        • iliketurtlez

          How do you access the files that are not in shared folders from your www?

          • Guilherme Akio Sakae

            In vagrant ssh, you can use the cd command like “cd /var/log” or “cd /etc/nginx/” to navigate through folders, vi or vim to edit files like “vim access.log” or any other unix command. Vagrant ssh works exactly like a normal ubuntu server (If you are using that os).

          • Did Guilherme’s response answer your question, or did you mean something else?

  • thanks kindly. glad you liked it.

  • Matt

    Very informative article, thanks. I can understand how easy it is to build a VM using Vagrant. It’s certainly a lot easier then building everything by hand. However, currently I’m using MAMP (pro) for running a AMP stack on my local machine and one advantage of that is that it’s very, very easy to add new testdomains. Open the GUI of MAMP, add a domain name, pick the disk folder it should match to and click restart of server. One minute, tops. I run 50+ sites at the same time now.

    So how would that translate to Vagrant? You wouldn’t create new VMs for each local webapp, right? And if you use one VM for running and testing many websites, how easy is it to add new dev domains? What impact does constantly running such a VM have on the performance your computer? I know that running VMware is a real performance drain, I wouldn’t want to have that running all the time.

    • iliketurtlez

      You don’t have to create new VM’s, no. You’d just have 50 folders inside your webroot like you currently do. As for vhost .dev domains, it depends on the puppet-apache-module. I haven’t found one I liked yet. You could theoretically go back to PuPHPet’s website and add new vhosts that way, and extract a whole nother VM to build, but yeah, it’s not as easy as just opening Apache’s vhost conf file.

      This is apparently what the pros are doing these days, where everyone needs the same development environment. I suppose once you and I learn how to configure apache puppet scripts, we might not look back. Between git, grunt, and composer, and now VM local dev environments, we have no choice but to get used to the command line, lest we become dinosaurs!

      • Hey folks, I don’t have access to my files right now, but will post a sample later. You should only need to copy and adjust an existing vhost configuration in puppet/common.yaml and then run either vagrant up –provision or if you have a running vm, call vagrant provision. I’ll update this comment later, when I have access to my files.

  • iliketurtlez

    Good post. This is like the missing manual for PuPHPet. Even though it’s meant to make it easier for someone new to Vagrant, Puppet, and Virtualboxes, it’s still a couple steps above someone coming from WampServer or XAMPP. I don’t know what Apache or PHP modules I need, that’s why I used WampServer! And it shouldn’t let you pick options that will make it refuse to install, breaking it from the get-go, but it does (set the same user and password for both MySQL and the default database you create, woops). I never did get it to correctly install phpMyAdmin. It gives lots of other errors too, and from Googling, it’s because the Vagrantfile is missing: = “bash -c ‘BASH_ENV=/etc/profile exec bash'”

    • I had a number of issues when I first started using it. It seemed to work, then it didn’t. Then it wouldn’t fully provision and so forth. But with the right combination of Vagrant and Puppet, it works like a charm and I really mean that. However, as Bruno pointed out to me recently, there’ve been changes in Vagrant and Puppet which may cause problems for a while. Disappointing, but true. So please make sure you read the two notices at the top of the PuPHPet page

  • Adnan Mulalić

    Good article of good tool… I have used Vagrant already and it’s great but I have one big problem with it. I had often situation where I leave computer on which is installed vagrant virtual machine and after computer go to suspend mode for some reason after start up computer the virtual machine don’t work. Vagrant say that there is no virtual machine created. After running “vagrant up –provision” vagrant create new virtual machine and everything work like before except that my database data was deleted because MySQL server was installed from beginning.This doesn’t happen every time but when happen it’s disappointing.

    • Try running vagrant up without the –provision. This will make it not reinstall the server when you boot it back up. You should also consider making SQL backups and include that in the provision – so even if you do run –provision, you still get your data automatically inserted.

      • Adnan Mulalic

        I will try when happen next time, but if I remember good, on ‘vagrant up’ it will be installed from beginnings too, like a fresh install (new virtual machine) and the old one stay in VirtualBox in some broken state. I will post in more detail when it happen again, if happen. The second safer option by creating SQL backup and including in provision work well.

        • On “vagrant up” it will re-provision things ONLY if you stopped the VM with Vagrant Destroy, because destroy tears it all down. If you stop it with halt or suspend, then nothing will be reinstalled on vagrant up. I’m not sure which signal happens when your computer goes into suspend mode, though…

  • Mufleeh Sadique

    Hi, thank you for the great article. I’ve been closely following the steps and when I run the command ‘vagrant up’, it stops in the line, ‘Waiting for machine to boot. This may take a few minutes…’ and shows the following message.

    I tried doing all from the beginning but no change. Do you have any idea why this happens?

    • “and shows the following message”, which message?

      • Mufleeh Sadique

        I am sorry just noticed that I have missed it. The one I receive is as follows,

        [default] Waiting for machine to boot. This may take a few minutes…
        Timed out while waiting for the machine to boot. This means that
        Vagrant was unable to communicate with the guest machine within
        the configured (“config.vm.boot_timeout” value) time period. This can

        mean a number of things.
        If you’re using a custom box, make sure that networking is properly
        working and you’re able to connect to the machine. It is a common
        problem that networking isn’t setup properly in these boxes.
        Verify that authentication configurations are also setup properly,
        as well.

        If the box appears to be booting properly, you may want to increase
        the timeout (“config.vm.boot_timeout”) value.

        • Maybe your host machine is too slow, and it hits the timeout. Did you try increasing it?

          • Mufleeh Sadique

            Well, I did it on the Vagrantfile, in fact the parameter wasn’t there but I added it and set to 3000. Is that correct? However it still gives me the same message.

          • Try increasing it further. I have a ridiculously powerful computer and it still takes me up to 5 minutes for a box to boot up fully. How long did you wait before that message happened?

          • Mufleeh Sadique

            Thanks and I turned it to 30,000, this time. But shows me the same message.

            Just to mention that in all these attempts, I see a copy starts running when I open the VM Virutal Box Manager. And when I run the command again (vagrant up) it gives the following message,

            Bringing machine ‘default’ up with ‘virtualbox’ provider…
            [default] VirtualBox VM is already running.

          • If it’s running, then it’s running. It worked. The VM will keep running now until you tell it to stop with vagrant halt (which only shuts it down) or vagrant destroy (which deletes everything it did, and lets you re-run the entire vagrant up command – useful if some software got only partially provisioned aka installed).

          • Mufleeh Sadique

            Thank you! to progress when I run the command ‘vagrant ssh’ I see this,

            ssh_exchange_identification: read: Connection reset by peer

            is it the Windows (7) having compatible issues or anything?

          • Try installing Git and Git tools, and using Git Bash to do vagrant ssh.

          • Mufleeh Sadique

            Hi, I got through now, and when I run the command sudo netstat -tlnp the one appears is not identical to the one given above, importantly this is missing,

            tcp6 0 0 :::80 :::* LISTEN 31623/apache2

            It looks strange because apache is supposed to be there right?

          • Yes, means the provisioning process didn’t finish and apache isn’t running and/or installed. Try running vagrant destroy and then vagrant up again, see what happens now that you have Git’s bash.

          • Mufleeh Sadique

            Yes, it progressed and ended as follows,

            Notice: Finished catalog run in 782.58 seconds

            Stderr from the command:
            stdin: is not tty
            Error: Comman exceeded timeout
            Error: Stage[main]/Puphpet::Apache::Modpagespeed/Exec[download apache mod-pagespeed to /.puppet-stuff/mod-pagespeed.dep]/returns: change from notrun to 0 failed: Commande exceeded timeout

            Is that a problem?

          • Yes, please try a different version of Vagrant.

          • Mufleeh Sadique

            Hi, managed to get this done :) will focus on the next one. Thanks for all support!

Get the latest in PHP, once a week, for free.