How to improve local WordPress development on a Mac

44 Comments

I love tweaking my workflow. I’m sure I’m not alone in that. When it comes to building things online, I’m always curious whether the way I’m doing things could be improved and better thought out. In the past I’ve shown how to set up a local WordPress development environment on a Mac. That tutorial is still solid, but I’ve made some additions to my setup this week that some of you may find interesting.

I have to credit my inspiration to seeing Ptah Dunbar and Andrew Nacin’s individual setups, very briefly, during their presentations at WordCamp Miami last weekend. They are both very accomplished developers, so of course my eyes are way open when they start navigating their desktops. Elements of their setup that I saw and liked I’ve used here, so thanks guys!

In this tutorial I will show you how to set up WordPress installs using MAMP in your Mac /Sites directory, how to set up multiple localhost aliases, and briefly talk about the various versions of WordPress I keep on my Macs.

The first thing you will want to do, without a doubt, is use and understand the earlier tutorial explaining local WordPress installation on a Mac. This tutorial will assume that knowledge, as well as in part that very setup. After all, that’s what I started with too.

We want to accomplish a few key things:

  • Instead of one local WordPress install at wp.dev, we want multiple installs. In this case we’re going to set up wp.dev, wp.bleeding, wp.3.0, and bp.dev.
  • Instead of storing our sites in the MAMP /htdocs folder (ugh) we’ll set all of our sites up in the Mac’s /Sites directory. Seems fitting, right?
  • I’ll briefly show how I use SVN and Git in conjunction with my local setup.

Okay? So let’s do it.

Step 1: Add the development folders to Sites

First thing we want to do is add the various folders we will develop with, and set up WordPress within them. So head over to your Sites folder, which should be within your Mac’s home directory (along with Documents, Library, and Music).

There will likely be an /images folder and index.html stand-in there. Delete them, we won’t be using those. Now add a few folders of your own. Which folders you add exactly will be up to you. Here’s what I chose to add:

  • wp.dev: The latest stable version of WordPress. If I need to work out an idea, build a theme, or test something out, here’s where I’ll go.
  • wp.bleeding: This is for the bleeding edge version of WordPress. Nightly updates go in here, where I can see what’s coming and (hopefully some time, in my case) begin contributing code back to WordPress.
  • wp.3.0: This is just for WordPress 3.0, a previous version of WordPress. While I’m beginning with just one version back, in time I may add folders for versions going all the way back to the earliest.
  • bp.dev: I like to keep an eye on BuddyPress development, and prefer an install specifically for testing out new features and themes that use its capabilities. This is for the latest stable version of BuddyPress + WordPress.
  • gooroo.dev: This one is project specific, for me. GooRoo is the business that WPCandy is a Β part of, so I use this particular folder to keep a copy of my GooRoo WordPress install, for testing and adding new features. I’ll get more into the unique qualities of this one below.

So that’s it for me. The latest stable version of WordPress, the bleeding edge, old versions, BuddyPress, and project-specific installs. Like I said, what you choose to set up is up to you. Whatever you decide, add a folder for each install you plan on setting up. Then, download the various versions of WordPress you will need and add them to the appropriate folders. Don’t worry about setting each version up, we’ll get to that.

We have our folders in place. But we want to be able to access them using our aliases, and of course connect to MAMP databases. Let’s do those next.

Step 2: Set up localhost aliases to point to Sites folder

This will feel familiar if you’ve gone over the previous tutorial: pull open Terminal, it’s time to edit the hosts file. Tap in:

sudo nano /private/etc/hosts

And hit enter to pull open the hosts file. You may need to type in your Mac password here.

You likely already have added a line to your hosts file in the past, pointing your local IP number to an alias like wp.dev. That’s what I had previously. Feel free to leave it if you have it, since we’re only going to be augmenting that line with a few more.

At the bottom of the list, make sure these are added:

127.0.0.1 wp.dev
127.0.0.1 wp.bleeding
127.0.0.1 wp.3.0
127.0.0.1 bp.dev
127.0.0.1 gooroo.dev

That last one you can skip, or make project-specific if it fits your needs. Now, what we’ve done is set up various aliases, all pointing to your local machine. This tells our Mac to not try and find a website when we type these into our browser, but to send these requests directly to your local machine. Awesome, right?

Problem is, they are all treated the same right now. We want each alias to go to a different place. So it’s time to dive a wee bit deeper. It’s time to edit our VirtualHost file.

Excited? Let’s go.

Step 3: Point the various aliases to the correct location

This particular step tripped me up for some time. Well, this step technically didn’t. It was the process of discovering that I needed this step that tripped me up. The steps are actually quite easy once you know them.

On a Mac, the VirtualHost.conf file determines where your localhost aliases are sent to (among other things that we won’t be digging into here). So we’ll need to edit that file and give it new instructions. Using TextMate (or your text editor of choice) turn on “Show hidden files” and navigate to Macintosh HD/private/etc/apache2/httpd.conf. Scroll down to around line 465 and look for these lines:

# Virtual hosts
#Include /private/etc/apache2/extra/httpd-vhosts.conf

Take the pound sign away from the second line, uncommenting it to look like this:

# Virtual hosts
Include /private/etc/apache2/extra/httpd-vhosts.conf

While you’re in that file, do a find on “PHP5”, which should bring you to around line 115 where you’ll see a line that looks like this:

#LoadModule php5_module libexec/apache2/libphp5.so

Go ahead and uncomment that line as well. We want PHP running.

Save and close that file. Now don’t get too excited: all we’ve done is told the computer to listen to our custom virtual hosts, which we’re about to add. Time to open another file.

In the same way, navigate to and open Macintosh HD/private/etc/apache2/extra/httpd-vhosts.conf. You should see a file around 40 lines long, with a couple of virtual host entries. These are sample entries, so we’ll be replacing the data that’s there with our own and deleting them.

First, let’s be sure we have an elementary understanding of what we’re doing here.

<VirtualHost *:80>
ServerAdmin [email protected]
DocumentRoot "/usr/docs/dummy-host.example.com"
ServerName dummy-host.example.com
ServerAlias www.dummy-host.example.com
ErrorLog "/private/var/log/apache2/dummy-host.example.com-error_log"
CustomLog "/private/var/log/apache2/dummy-host.example.com-access_log" common
</VirtualHost>

I won’t claim to understand all of what these lines mean. We’re standing very close to the shore of my understanding; much deeper and I’ll be lost. What I do know is that we will need only the DocumentRoot and ServerName lines to achieve what we’re after. The VirtualHost entry for my wp.dev location, for instance, is:

<VirtualHost *:80>
DocumentRoot "/Users/ryanlaptop/Sites/wp.dev"
ServerName wp.dev
</VirtualHost>

So what this is doing is taking the ServerName and then delivering up the pages found at DocumentRoot. Cool, right? Now let’s add a few more of those, one for each of our local WordPress installations. Mine now looks like this:

<VirtualHost *:80>
DocumentRoot "/Users/ryanlaptop/Sites/wp.dev"
ServerName wp.dev
</VirtualHost>
<VirtualHost *:80>
DocumentRoot "/Users/ryanlaptop/Sites/wp.bleeding"
ServerName wp.bleeding
</VirtualHost>
<VirtualHost *:80>
DocumentRoot "/Users/ryanlaptop/Sites/wp.3.0"
ServerName wp.3.0
</VirtualHost>
<VirtualHost *:80>
DocumentRoot "/Users/ryanlaptop/Sites/bp.dev"
ServerName bp.dev
</VirtualHost>
<VirtualHost *:80>
DocumentRoot "/Users/ryanlaptop/Sites/gooroo.dev"
ServerName gooroo.dev
</VirtualHost>

One more step complete. If all has gone well up to this point, you should be able to see the effect. Be sure to save this file, then visit System Preferences > Sharing and cycle Web Sharing. What I mean is, turn Web Sharing off and then back on again. This restarts Apache so that your computer will find these changes that you’ve made.

Assuming this has worked for you so far, you should be able to visit wp.dev or wp.bleeding, for instance, and see the correct folder. On to the next step!

Step 4: Connect to MAMP databases

So we have the aliases pointing to our Sites folder, now we just need to connect to our MAMP databases. Since you’re somewhat comfortable with MAMP, I won’t walk you through the process of creating a database within it. But when you are filling out the config.php files within your new WordPress installs, in your Sites folder, you will want to make one key change. Rather than leaving the hostname to “localhost”, the default, you will want to use:

localhost:/Applications/MAMP/tmp/mysql/mysql.sock

That will locate and connect to the correct MySQL databases.

Step 5: Step back and consider…

So let’s think about what we have here. We have various WordPress installs, relevant to our workflow, sitting in our Sites directory only a few keystrokes away with our special aliases. What more could we want?

I would recommend taking advantage of your new setup to learn about Subversion. You can use SVN, for instance, to pull down the latest stable, or nightly, versions of WordPress into your various folders. This would be a really quick way to keep everything up to date.

Or, you could do what I did with my project development folder. I set up a private Github repository for just my /wp-content folder, within gooroo.dev. So I can do all feature testing and development locally, then push those changes up, and pull them into the GooRoo server seamlessly.

You can obviously use whatever methods you like once you’re to this point, but I would encourage some sort of version control for your work, particularly if you, like me, work on a desktop computer at times and on a laptop at times. Using various version control systems with WordPress is a bit outside of this tutorial, though. Next time.

Addendum: Enabling .htaccess

So it turns out there is one extra step that I overlooked when I put this together. I ran into it this morning when I went to set up a multisite network. .htaccess rules aren’t enabled by default in the /Sites folder. So let me save you (and future me) a few minutes and talk you through what you need to do.

There are two files that need to be edited. One is your httpd.conf file (again) and then another, user-specific .conf file.

So first open up httpd.conf again (see above for where that file is located) and search for the text “AllowOverride”. This will bring you to a comment block describing “what directives may be placed in .htaccess files.” This is what you’re after. Change the line AllowOverride Nonce to AllowOverride All. Then save and close, we’re done with this one.

Next you’ll be editing your user-specific .conf file. This will be named differently depending on your setup, but mine was located at:

Macintosh HD/private/etc/apache2/users/ryanimel.conf

So pull that one up, and make sure it looks like this:

<Directory "/Users/YOURUSERNAME/Sites/">
     Options Indexes MultiViews FollowSymLinks
     AllowOverride All AuthConfig
     Order allow,deny
     Allow from all
</Directory>

Save and close that file. Then restart Apache (by turning Web Sharing off and then back on again) and .htaccess rules should work within your Sites directory.


Now I have a question for you: was this helpful? Have you ever wanted to do these things, or at least know how to do them in case you ever want to? It’s likely a very niche topic to cover, but after the number of hours I spent tracking down solutions at each step here, I thought it only right to share it with others. Hey, maybe it will save a few of you some time!

Oh, and one other question: how many different versions of WordPress do you have installed locally on your machine?

44 thoughts on “How to improve local WordPress development on a Mac

  1. Hey,

    Nice post…and great timing! I was actually right in the middle of this when the post came through my feed πŸ™‚

  2. Great stuff, Ryan. I use MAMP and a local WordPress environment for nearly all my development. There are some great tips here, so I’ll be sending other folks here as well. Thanks!

  3. This is fabulous! I used XAMPP instead of MAMP when I configured mine a few weeks ago. I’ll have to explore the virtual host configuration there.

    I worked around the separate name by referring to each installation as a subdirectory. Also, your browser can find your machine by its name instead of localhost. My MacBook Pro is called icecrystal, so I use http://icecrystal.local/wp1/ to access one installation. You could use http://icecrystal.local/edge/ for a bleeding edge installation. (For some reason OSX appends the .local to the machine name. I don’t know why. My PC doesn’t do that.)

    I have 2 or 3 installs on my MacBook right now, but I have 15 or more installed on my PC running XAMPP. I use them as development sites for editing themes and playing with plugins for different clients.

    Great article! Thanks for sharing.

    • That’s a clever way to do it too. Subfolders are honestly the easy, sane person way to go about this :). Once I decided I wanted a cool top level reference for each of my installs, I fought my way through Google and trial and error until I figured it out and understood it.

      Do you find you use a new install for various projects, or do you keep old versions around in old installs? I’m curious what those 15 or so on your PC are.

  4. love this man, and excited to try it! Right now I have my sites set up in in the /Sites folder, and anytime i want to access a different one, i just go into MAMP’s preferences & change the document root. So This should take out that step, right? and i should be able to run two of these installs in my browser at once? If so, that’s very exciting! Thanks for posting this.

  5. Hi, great post! I’m wondering though why you would want to use a mixture of MAMP (for databases) and the built-in web server in Mac OS X. Doesn’t that get a bit complicated?

    • It doesn’t seem complicated to me, but I suppose it could be. My main reason for wanting to use the Mac Sites folder (aside from seeing Ptah and Nacin with a similar setup last weekend) was annoyance with setting up everything with the MAMP/htdocs folder. I just wanted to keep things in a more logical place, thus my new setup was born.

      • But there is no requirement in MAMP to use its own htdocs folder. Even the free version of MAMP has it’s own httpd.conf file, where you can define as many virtual hosts as you want (with the same syntax you used above). It’s located in /Applications/MAMP/conf/apache/httpd.conf

        Just add the virtual hosts rules at the end. I would think you could still use the Sites folder, as long as you have deactivated the in-built Web Sharing in Mac OS X.

        Of course, you could also use MAMP Pro, which has a nice GUI for setting up all the virtual hosts, but the capability exists in regular MAMP. πŸ™‚

        • Good to know. I guess I never tried working within MAMP to make it happen, just forged my own way. Finding out there is an easier way if only I would have known = the story of my life ;).

          • Yeah out of the box MAMP will let you use the Sites folder. In the Apache section in Preferences in MAMP, you can change your default location.

            In MAMP Pro, it’s in the Hosts section.

          • ETA: Yeah, you need to have Web Sharing off (but that’s a good rule of thumb when using MAMP anyway) but as long as that’s the case, you don’t even need to configure anything in httpd.conf unless you want to create custom domains — you can do everything you do now, just tell MAMP in the settings to use the Sites folder for its default location.

  6. You are inconsistent with wp.30 vs wp.3.0
    If someone to follow you instructions to a dot, things won’t be quite happening for this particular site.

    • Hey, thanks for the heads up. I think I’ve made all references consistent now, so we should be good to go.

      Do you use a local setup?

  7. No problem.
    I used to have XAMPP installed on my laptop but in the end I was forced to set up a stand-alone server for primarily two reasons.
    1. FireFox doesn’t like running on the same box with Apache and keeps peaking out the CPU
    2. it’s tricky to have IE6, 7 and 8 installed on the same computer but I kinda need to test with each of them.

    To answer you other question, my list of applications is pretty short:
    2 x Joomla 1.5
    Joomla 1.6
    Drupal 7
    2 X phpBB3
    and, of course,
    WordPress 3.0 localized
    WordPress 3.1 generic

  8. I have a similar setup on PC with XAMPP.
    I use a .local extension, for example wordpress.local for my dev installation.
    all sites are under My Dropbox/sites, so they are synchronized across any PC I use.
    all I’m missing is a version control to automatically deploy, like beanstalk, but that’s 15$ a month.
    maybe I can install subversion on my hostgator account to pull in new versions?

    • Check and see if HostGator has SVN already installed — a lot of hosts do — then you could just configure the .svn folders from the terminal using SSH and deploy that way (or use something like Coda to push out via SVN while editing local code).

  9. Thanks for taking the time to work all this out Ryan, but there is a way to do it that’s a heck of a lot easier. Open httpd.conf file in /applications/mamp/conf/apache. Now all you have to do is edit lines 368 & 393 with your desired location. In my case, it was /users/galen/sites but I guess anything would work. I did a dummy installation of WordPress and everything worked great. Thanks for inspiring me to figure this out though!

    • Story of my life :). I’m glad I learned how to do it this way, though. Makes me feel smarter. Thanks for the heads up on that though!

  10. Something that’s never explained in these tutorials (no offense meant), is how y’all keep your posts, comments, etc (database) and wp-content/* content synchronized (like uploads/*, themes/*, plugins/*)?

    Do you copy them over from your production blog and change (hard coded) links/urls to local paths? Or am I missing something here?

    I’d like for my dev sites to mimic the production sites as much as possible, so I can immediately see how it eventually will look on the production site in an article or home page view. Or do you just work with dummy content?

    I’d like some additional explanation on this topic if anyone wants to touch on that. And of course many thanks for the excellent tutorial. I’ve had this exact setup running, but the content synchronizing was getting way too cumbersome πŸ™ Some pointers would be most helpful.

  11. Great Read,
    Love it! I’m always fascinated about how other users setup their workflow, I bit the bullet and purchased MAMP Pro which handles all the Hosts and File Locations, however your detailed walkthrough is very useful and something I am well keen to try out!
    As for how many local installs of WordPress do I run.. :] oh just about 58 so far… I do a clean out every 6 months, most work is on SVN but you can never be too careful..
    @jean-paul horn I use SVN so all my files etc are saved, then do a mysqldump and populate the dev environment with an svn up and mysql command,, a little more work but well worth it.

    best
    jeff

  12. Pingback: Michael Fields » Plugin Palooza

  13. Hi,
    I’m a WordPress semi-newbie, not a developer. I’ve set up a couple of pretty simple sites. I’ve been searching all over the web for some help with setting up multiple WordPress sites on my Mac, and ran across this article. As a newbie, (and, by the way, a fairly new Mac user), some of the most basic things escape me and I’d be grateful for some help here. The reason I attempted to try your method is because of the article’s clear, step-by-step instructions.

    Except….

    when you made a couple of assumptions, i.e. “Since you’re somewhat comfortable with MAMP…”

    I created two new databases in myPHPadmin, just typing in the new names used earlier and selected “create”, yes? I made the changes in the wp-config.php files in the new WordPress installs in the Sites folder as instructed.

    Now *blush* I have no idea as to how to call the new wp-admin/install.php programs in order to complete the installation. I know this is pretty basic, but I’d be grateful for the help. What would the URL be for the new sites? I have one local installation already that I call with http://localhost:8888/.

    After reading the above comments to your article, I’m pretty intimidated and hesitated to post this, but I’m desperate.

    Thanks!

  14. Hi Thanks first of all
    I have a silly question but since my understanding doesn’t go that far, once I’ve done all you say, how do i point to my local installation of WordPress from the browser?

  15. Hi Ryan,
    when I get to step 3, these files are not on my machine.
    # Virtual hosts
    #Include /private/etc/apache2/extra/httpd-vhosts.conf

    I’m using MacOS X version 10.4.11, could this be the problem.
    Please help this is diving me mental.

    greetings

    scot

  16. Pingback: Adding Git to your WordPress development workflow

  17. Pingback: Adding Git to your WordPress development workflow

Comments are closed.