I decided yesterday that I wanted to break up with MAMP. While it (and XAMPP) have served their purpose well over the last year or so that I’ve been using them on a regular basis, they don’t come close to mirroring some of the most common server setups out there today for the development that I’m doing.
I want to break up with MAMP.
— Jeremy Felt (@jeremyfelt) December 10, 2012
Most of the smarter setups for PHP dev these days include some combination of nginx, mysql, php-fpm and memcached – at least. The thought of trying to get all of these packages installed and working on a local OS X machine is overwhelming. This computer of mine should be a laptop, not a server.
Luckily, I’m not alone in this dilemma and I got a couple of great replies right off the bat. One came from Tom Willmot pointing me toward some fantastic onboarding docs for Human Made on GitHub that walk through setting up services in OS X. I started down that path because it looked great, but I was also tempted by a reply from Micah Godbolt asking if I had been keeping an eye on Vagrant. That temptation ended up winning the night.
Enter the virtual machine.
I had heard of Vagrant briefly, but had never given it a full chance. I was probably in one of those modes where I would move on if I couldn’t figure it out in less that two minutes. This desire to break up with MAMP finally gave me the will power needed to put in more time.
It turns out that Vagrant is freaking wonderful.
And just over 24 hours later, I have my first draft of a provisioned server up on GitHub as Varying Vagrant Vagrants. It’s fantastic.
I am now able to fire up an instance with a simple ‘vagrant up’ that automatically installs nginx, php-fpm, mysql before proceeding to move config files around and import SQL dumps so that just minutes after the initial command, I can go to an existing dev site in my browser or initiate a brand new WordPress install.
So now I’m on the hunt for more. I’m going to head over to the Portland Drupal User Group meeting tomorrow night for a demo on Vagrant and Puppet and I’m now hoping to start filling my brain with everything Vagrant. There are so many possibilities for sharing dev environments with team members and I can see this turning out to be a ton of fun.
With all that said, get over to GitHub and fork Varying Vagrant Vagrants to see for yourself. I’ve done my best to include some documentation that should get you all the way there, but feel free to reach out if you need some help.
So you’ve done your due diligence and gone to great lengths to make sure that your WordPress server setup is top notch.
How do you know it’s working, besides that things seem quick?
The obvious answer is to open an incognito or private window in your browser, visit the site in question, and then view source on the page load. In the <head> area, there should be a comment left by Batcache providing statistics on when and for how long it was generated.
However, the easy answer is not always the most fun answer. And not every answer tells the full story. Checking the reponse headers of the HTTP request can also fill you in on some extra info.
Batcache by default is set to only start serving cached page views if a page has been accessed more than twice in a 120 second period. It also should only be serving these cached views to unauthenticated users. Before you’ll be able to see the entire package in action, you need to load whichever page you want to test a few times as a non authenticated user, and then check the headers. If you have a command prompt with curl installed, your easiest option is this:
curl http://mydomain.com/ curl http://mydomain.com/ curl http://mydomain.com/ curl -I http://mydomain.com/ curl -I http://mydomain.com/
Do these in quick succession, ignoring the page content that you receive after the first 3 commands. Hint, hint.. use the up arrow. Feel free to ignore me too, because right now I’m hitting it after one page view, so who knows what I did.
After the fourth command, issued with the -I flag that tells curl to only make a HEAD request, your should see output indicating that Batcache has caught the request and is attempting to work some magic.
HTTP/1.1 200 OK Server: nginx Date: Mon, 10 Dec 2012 06:19:30 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive X-Powered-By: PHP/5.3.6-13ubuntu3.9 Vary: Cookie X-Pingback: http://mydomain.com/wordpress/xmlrpc.php Link: <http://little.shorty/2aYLe>; rel=shortlink Last-Modified: Mon, 10 Dec 2012 06:19:30 GMT Cache-Control: max-age=300, must-revalidate
The last two lines in this HEAD output are key. Cache-Control has been turned on, and the max-age of the request has been set to 300 seconds. Sweet! This means that at least one thing is doing something – Batcache.
Now, the second curl request made with the -I flag gives us almost the same information:
HTTP/1.1 200 OK Server: nginx Date: Mon, 10 Dec 2012 06:42:45 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive Last-Modified: Mon, 10 Dec 2012 06:42:43 GMT Cache-Control: max-age=298, must-revalidate X-Powered-By: PHP/5.3.6-13ubuntu3.9 Vary: Cookie X-Pingback: http://mydomain.com/wordpress/xmlrpc.php Link: <http://little.shorty/2aYLe>; rel=shortlink
You’ll notice here that the Cache-Control line has moved up a bit and the max-age of the request has been set to 298 seconds. This means the timer on the cache expiration has started to count down. If you were to keep on making curl -I requests at this point, you could expect that timer to count all the way to 0 before the page cache was regenerated.
The ordering of the lines in these examples may not always match, but if you do this curl -I request multiple times and max-age stays at 300, this is probably an indication that while Batcache is doing what it needs to do, there is no actual caching going on in the background. At this point, check to make sure that you have an object cache plugin installed and that Memcached is in fact running.
Of course, sometimes it isn’t as easy as just making sure everything is running. Batcache and Memcached may be running fine, but if there’s a PHP Session to be maintained, then the Cache-Control header will probably not be modified and you’ll see something similar to this:
HTTP/1.1 200 OK Server: nginx Date: Mon, 10 Dec 2012 06:06:33 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive Last-Modified: Mon, 10 Dec 2012 06:03:29 GMT X-Powered-By: PHP/5.3.6-13ubuntu3.9 Vary: Cookie Set-Cookie: PHPSESSID=dpbnobn95jrgg5fhpfaa5sn707; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache X-Pingback: http://mydomain.com/wordpress/xmlrpc.php Link: <http://little.shorty/12345>; rel=shortlink
At this point, you’ll need to go back to relying on the comment left by Batcache in the page source to determine if it is still generating things as intended. Though it may be work a search for ‘session_start()’ through your code base to see if you really need that PHP Session, as this could be negating some of what you are hoping to achieve through caching anyway.
Oh, and if nothing is turned on at all, expect something similar to this:
HTTP/1.1 200 OK Server: nginx Date: Mon, 10 Dec 2012 06:21:48 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive X-Powered-By: PHP/5.3.6-13ubuntu3.9 X-Pingback: http://mydomain.com/wordpress/xmlrpc.php Link: <http://little.shorty/2aYLe>; rel=shortlink
Notice no Cache-Control header at all when Batcache is out of the picture.
All of the above is intended to be taken with a grain of salt. I didn’t research too much of it thoroughly, and a lot is dependant on my specific environment. It may come in handy to a few though, and it’ll probably come in handy to myself again.