6 Vagrant provisioning wins

Six solid provisioning snippets that serve me well and make developing and provisioning with Vagrant a little bit easier.

How to Provision a box

The most basic form of provisioning is via shell commands and the two simplest ways to do so are with an inline script in your VagrantFile or with an external bootstrap.sh.

This page on Vagrant docs provides everything you’ll need to use these snippets and more, but the crux of it is that you can either add config.vm.provision "shell", path: "script.sh" to your VagrantFile and put provisioning scripts in a file called script.sh or you can put provisioning scripts directly in your VagrantFile like so:

config.vm.provision "shell", inline: <<-SHELL
    # Provisioning scripts here...
SHELL

Note that I’ll be using Scotchbox as an example so if you use a different box (e.g. Homestead) you may need to adjust database credentials and/or file paths.

1. Restore a MySQL database

Undoubtedly the simplest of the snippets is to restore a MySQL database and is useful for schema creation and database seeding, e.g. one .sql file for WordPress database schema and another for some dummy data.

The following one-liner will restore an exported MySQL database:

mysql -u root -proot scotchbox < /var/www/database.sql
  1. The first root is the MySQL username
  2. The second root is the MySQL password
  3. scotchbox is the database name
  4. /var/www/database.sql is the path to the database backup

Note that #4 is relative to the VM, not your host machine.

To create the backup in the first place run:

vagrant ssh
cd /var/www && mysqldump -u root -proot scotchbox > database.sql

or if you’re updating a backup you’ve already taken, use:

vagrant ssh
cd /var/www && rm database.sql && mysqldump -u root -proot scotchbox > database.sql

2. Install xDebug

The xDebug PHP extension provides better display of exceptions including stack traces plus pretty var_dump()ing which makes inspecting variables a smidgen easier, particularly complex array structures.

However much I like Scotchbox, they intentionally omit xDebug to KISS, saying it would confuse inexperienced developers. Personally, I think PHP’s standard plaintext errors are more confusing and provide insufficient debug information — if you agree, the following snippet will install xDebug painlessly:

sudo apt-get install php5-xdebug -y
echo "" >> /etc/php5/apache2/php.ini
echo "; xDebug" >> /etc/php5/apache2/php.ini
echo "xdebug.remote_enable = 1" >> /etc/php5/apache2/php.ini
echo "xdebug.renite_enable = 1" >> /etc/php5/apache2/php.ini
echo "xdebug.max_nesting_level = 1000" >> /etc/php5/apache2/php.ini
echo "xdebug.profiler_enable_trigger = 1" >> /etc/php5/apache2/php.ini
echo "xdebug.profiler_output_dir = '/var/log'" >> /etc/php5/apache2/php.ini

3. Working with WordPress

Plugins & Themes

It’s often desirable to develop plugins and themes outside of the WordPress instance using symlinks, but Vagrant provides an equally-simple solution in the form of synced folders:

config.vm.synced_folder "/Users/rich/WordPress/Plugins", "/var/www/public/wp-content/plugins", :mount_options => ["dmode=777", "fmode=666"]
config.vm.synced_folder "/Users/rich/WordPress/Themes", "/var/www/public/wp-content/themes", :mount_options => ["dmode=777", "fmode=666"]

This will create a shared folder that places a development folder on my host machine in place of the WordPress plugins and themes folders. Super simple and means that if multiple VMs use the same plugin, updating one updates them all.

Performance

I’ve had performance issues with WordPress due to networking problems related to DNS lookups preventing it from checking for updates via api.wordpress.org.

The quick fix is to add an entry to /etc/hosts which avoids the lookup altogether:

echo "66.155.40.202 api.wordpress.org" >> /etc/hosts

4. Update and reload

If you’re installing software as part of provisioning or editing config files (e.g. xDebug) you’ll want to update your repository information for the former and possibly restart servers/reload configuration for the latter.

That means putting sudo apt-get update before any installations and, if you use Apache, sudo service apache2 reload afterwards.

5. Edit config files

Say you need to change upload_max_filesize in php.ini, if you know the default value for your box you can use something like this snippet to change a value:

sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 20M/' /etc/php5/apache2/php.ini

6. Reprovision without destroy

Finally, if you’ve made changes to your VagrantFile but don’t want to sit through a destroy and up cycle, you can reload your box (basically a quick reboot) and specify that you want to provision it and your changes will be applied:

vagrant reload --provision

Note that the entire provisioning process will be re-run and this may cause double-entries in config files and such so sometimes it’s best to destroy and rebuild a box, but I’ll leave it to you to decide when this is appropriate.

See the Vagrant docs for more information about when provisioning occurs.

BONUS: Fix stdin error

This isn’t an error as such insofar as it doesn’t indicate a real problem and can be safely ignored. Nevertheless it irked me so I found the solution is to add the following to your Vagrantile:

config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'"

This isn’t without it’s problems though. For most cases it’s harmless but for a full discussion please see this github discussion.

Conclusion

That’s my top 6 Vagrant provisioning wins, what’re yours? Let me know in the comments!

2 Comments

    • Glad you found this post useful! Docker seems to be the newest cool kid on the block but I still think Vagrant is a solid workhorse. Happy coding!

Leave a Reply

Your email address will not be published.