Matthew Setter’s last article on PuPHPet covered the easy GUI-backed creation of Vagrant VMs. PuPHPet is an absolutely awesome tool in getting up and running with a development environment really fast, and offers some very neat default options.

But what if we want to step outside the defaults? What if we’d, for example, like to install a PHP extension that isn’t part of the default distribution and doesn’t exist in package managers?

In this tutorial, we’ll make sure the Phalcon framework is installed by default when we run vagrant up. Pre-installing software on a Vagrant VM is called provisioning.

Getting ready

Please walk through Matthew’s article before moving along with this one. Simply make sure you download a ready PHP-enabled VM.

In this particular case I used PHP 5.4 with Ubuntu (5.5 won’t work with it just yet via PuPHPet), but if you’ve got your own configuration you’re used to, please feel free to use it – just make sure you can get to a good phpinfo screen before continuing. Make certain your PHP configuration works and you can access the VM through the browser and execute a PHP script like


Ideally, your browser should display something like this:

The basics of Provisioning

Vagrant offers several ways to provision software into your Virtual Machines. There’s Puppet (what PuPHPet is based on), Chef, Docker, and more. What we’ll be using is pure good old shell commands – Vagrant can execute a shell file we write if we pass it to its provisioning settings.

So, let’s say you need to install the text editor joe and want to do it through shell. In your PuPHPet folder’s shell subfolder, you would create a file with the following contents:

sudo su
apt-get install joe

This shell script first identifies itself as executable by bash (optional), requests superuser permissions, and then it installs joe through the regular channels. To actually have this executed, we modify the Vagrantfile in the PuPHPet folder by adding the line

config.vm.provision :shell, :path => "shell/"

under the last config.vm.provision... line/block. Now if we run vagrant up in our PuPHPet folder, our VM will have joe installed as soon as it boots.

Installing Phalcon

As per Phalcon’s online installation instructions, the compilation process is straightforward:

git clone git://
cd cphalcon/build
sudo ./install

However, we also need to enter into the PHP configuration, restart the server, and make sure all the prerequisites are installed (they are, PuPHPet took care of that for us). Let’s do this step by step.

In the shell subfolder again, create the file Give it the following content:

sudo su
git clone git://
cd cphalcon/build
cd ..
cd ..
rm -rf cphalcon

Now if you re-run vagrant up after running vagrant destroy, you can see the extension in the PHP extensions folder:

However, in order for it to actually be used, needs to be added to the PHP configuration. After adding it, we also need to reload the server in order to load the new configuration. Improve the shell file above by adding the following statements to the bottom:

echo '' > /etc/php5/mods-available/phalcon.ini
ln -s /etc/php5/mods-available/phalcon.ini /etc/php5/cli/conf.d/phalcon.ini
ln -s /etc/php5/mods-available/phalcon.ini /etc/php5/apache/conf.d/phalcon.ini
ln -s /etc/php5/mods-available/phalcon.ini /etc/php5/fpm/conf.d/phalcon.ini

service apache2 restart

First, we create a phalcon.ini file in the /etc/php5/mods-available directory. We could echo it directly into php.ini, but this is just cleaner. Then, we symlink that newly created file to all the locations from where PHP can be run: Apache, command line and FPM. That way, all our potential PHP runtimes have Phalcon available. Finally, we restart Apache.

If you try running vagrant up now (after running vagrant destroy), you’ll notice the phpinfo screen displaying Phalcon as loaded after you re-visit the VM’s IP in your browser.

But what if the server process is named differently? For example, if it’s “httpd”, or just “apache”, and not “apache2”? Furthermore, what if we’ve got a different distro? On CentOS phalcon.ini should go to /etc/php.d/, and on other distros into other locations. Finally, what if we only do a vagrant halt and then run vagrant up but force a re-provision with the --provision flag? Wouldn’t it be better to simply ignore the Phalcon installation if it’s already installed?

Luckily, slogsdon took all this into account for us. He built an excellent Phalcon installation shell script, ripe with IF clauses and more, and even created a phalcon-tools installation script.

To install Phalcon with all the above taken into account, place into the shell folder of your PuPHPet download, and add it to the provisioner like we did for joe before. If you’d like to install Phalcon tools, do the same with That’s all you need to do – the script accounts for different servers and setups so all you need to do is have it run.

Now you too can have an out-of-the-box ready Phalcon installation ready for development at the snap of your fingers. Naturally, you’ll need to do some additional tweaks to get URL rewriting to work on Nginx (just follow the Phalcon docs), but once the extension is installed and loaded by PHP, the hard part is over. What’s best, you can use this approach to install Phalcon on any of the PuPHPet supported environments as well – Digital Ocean, Rackspace or AWS. Just plug slogsdon’s shell into the provision settings, and you’re ready to go!


In this tutorial, we covered the basics of provisioning via shell and installed Phalcon (and joe) with a booting VM. Coming soon is a followup article from Matthew Setter which will deal with further customizations of the downloaded provision settings from PuPHPet.

To get familiar with the full workflow of Vagrant and Puppet, please do keep following this series as it’s about to get a whole lot more interesting!

If you have any comments, uncertainties, problems or just general feedback, please leave it in the comments below and I’ll do my best to address it as soon as possible! If you’ve got your own setup you’d like to share with the rest of us, do get in touch with me via +BrunoSkvorc and we’ll talk.

Bruno SkvorcBruno Skvorc
View Author

Bruno is a blockchain developer and technical educator at the Web3 Foundation, the foundation that's building the next generation of the free people's internet. He runs two newsletters you should subscribe to if you're interested in Web3.0: Dot Leap covers ecosystem and tech development of Web3, and NFT Review covers the evolution of the non-fungible token (digital collectibles) ecosystem inside this emerging new web. His current passion project is, the most advanced NFT system in the world, which allows NFTs to own other NFTs, NFTs to react to emotion, NFTs to be governed democratically, and NFTs to be multiple things at once.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week
Loading form