OS X Yosemite & El Capitan: How to Set Up Apache, MySQL, and PHP with Homebrew

The Perfect Local Web Development and Testing Server

Update December 2016: Things have changed quite a bit in macOS Sierra. We recommend this tutorial (part 1 & part 2) for setting up the Homebrew version of Apache and PHP. You can still use our version of the vhosts configuration to get xip.io support (see Step 5 below).

Maybe you want to use WordPress. Or maybe Kirby.
Maybe you just love PHP (which could be a reason to worry).

Whatever it is, you will probably be looking for an uncomplicated way to set up a local development server with Apache, MySQL, PHP, and virtual hosts on your Mac with Yosemite and El Capitan—a testing server for multiple local websites that is also easily accessible from other devices on the local network, so you can test websites live on your iPhone.

I’ve found some great tutorials, but I felt like I could combine them to make the process even easier and the result a little more powerful. So let’s go ahead and use the built-in stuff that your Mac has out of the box and sprinkle in some Homebrew packages.

WARNING: You will be messing with system files on your Mac in a minute. Follow these instructions only if you know what you’re doing. You should never, never ever paste anything into your terminal if you don’t understand what it does. And make sure to do a Time Machine backup first.

–2. Install Xcode Command Line Tools

… if you don’t already have them:

xcode-select --install

This will download and install the Xcode Command Line Tools. They are required to run Homebrew.

–1. Install Homebrew

Install the Homebrew package manager (or update it if you already have it):

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

0. Install Sublime Text

Skip this step if you know how to edit hidden system configuration files or if you already have Sublime Text.

If you don’t, simply download and install Sublime Text.

Then use this command:

ln -s "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" /usr/local/bin/subl

…which will let you use the subl command in the Terminal to easily edit system configuration files.

1. Install dnsmasq

We will use dnsmasq to automagically map any .dev domain to a folder of the same name in your Web directory (more on that later).

Paste this into your Terminal (line by line) to install and configure dnsmasq:

brew install dnsmasq
cd $(brew --prefix)
mkdir etc
echo 'address=/.dev/127.0.0.1' > etc/dnsmasq.conf
sudo cp -v $(brew --prefix dnsmasq)/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons

Enter your admin password. Then paste the rest:

sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
sudo mkdir /etc/resolver
sudo bash -c 'echo "nameserver 127.0.0.1" > /etc/resolver/dev'

2. httpd.conf

Edit /private/etc/apache2/httpd.conf

subl /private/etc/apache2/httpd.conf

… and uncomment these lines by removing the #:

# line 160
LoadModule vhost_alias_module libexec/apache2/mod_vhost_alias.so
# line 168
LoadModule rewrite_module libexec/apache2/mod_rewrite.so
# line 169
LoadModule php5_module libexec/apache2/libphp5.so
# line 499
Include /private/etc/apache2/extra/httpd-vhosts.conf

Add “index.php” in line 271:

<IfModule dir_module>
DirectoryIndex index.html index.php
</IfModule>

3. php.ini

Create and edit /private/etc/php.ini:

sudo cp /private/etc/php.ini.default /private/etc/php.ini
subl /private/etc/php.ini

… now remove the semicolon (;) in front of line 791 (Yosemite) / line 788 (El Capitan) and edit the line to look like this:

upload_tmp_dir = /tmp

… and remove the semicolon (;) from line 1390 (Yosemite) / line 1366 [or 1387?] (El Capitan):

session.save_path = "/tmp"

4. The Web Folder

Create a folder in your home directory called Web:

mkdir ~/Web

This is the folder where all your projects will live in subdirectories. If you would like to put it in a different location, make sure you also use the changed path in Step 5 below.

Inside the newly created folder, make another folder called _localhost:

mkdir ~/Web/_localhost

This is where you can put a default page that is shown when you navigate to 127.0.0.1 or to localhost in your browser, or if someone on your local networks enters your machine’s IP address in their browser.

5. httpd-vhosts.conf

Edit /private/etc/apache2/extra/httpd-vhosts.conf:

subl /private/etc/apache2/extra/httpd-vhosts.conf

Delete everything after line 22 and paste this (replace YOURUSERNAME with your home directory’s name):

<Directory "/Users/YOURUSERNAME/Web">
Options Indexes MultiViews FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
Require all granted
</Directory>
<Virtualhost *:80>
VirtualDocumentRoot "/Users/YOURUSERNAME/Web/_localhost"
UseCanonicalName Off
</Virtualhost>
<Virtualhost *:80>
VirtualDocumentRoot "/Users/YOURUSERNAME/Web/%2"
ServerName sites.dev
ServerAlias www.*.dev
ServerAlias www.*.dev.*.xip.io
UseCanonicalName Off
</Virtualhost>
<Virtualhost *:80>
VirtualDocumentRoot "/Users/YOURUSERNAME/Web/%1"
ServerName sites.dev
ServerAlias *.dev
ServerAlias *.dev.*.xip.io
UseCanonicalName Off
</Virtualhost>

6. Install MySQL

Paste this into your Terminal to install and configure MySQL:

brew install mysql
mysql.server restart
mysql_secure_installation

Follow the instructions on your screen. Don’t worry, it’s only a few steps and will make your MySQL installation much more secure.

Paste this into your Terminal to create a new database:

mysql.server stop
mysql_install_db --verbose --user=`whoami` --basedir="$(brew --prefix mysql)" --datadir=/usr/local/var/mysql --tmpdir=/tmp

OS X expects the MySQL socket to sit in /var/mysql, so we create that folder and add a symbolic link to where the socket actually lives:

sudo mkdir /var/mysql
sudo chmod 755 /var/mysql
sudo ln -s /tmp/mysql.sock /var/mysql/mysql.sock

Now try starting the MySQL server:

mysql.server start

You should now be able to use Sequel Pro access to your databases. Just enter the MySQL user name (the default is root) and the password (that you’ve created a minute ago) in the Socket tab and you should be connected.

7. Done!

You can now start Apache and MySQL like this:

mysql.server start
sudo apachectl restart

And quit them like this:

mysql.server stop
sudo apachectl stop

If everything has worked out, every folder you create in ~/Web like, say:

~/Web/myawesomesite

… will automatically be accessible as a .dev domain on your local machine as both:

myawesomesite.dev

… and:

www.myawesomesite.dev

And because you always want to test your sites on dozens of mobile devices and legacy windows machines, you can now also access it from other devices on your local network:

myawesomesite.dev.X.X.X.X.xip.io

…where X.X.X.X is, of course, your computer’s IP address.

If your router’s DNS blocks the xip.io service, you can set up Google’s DNS (8.8.8.8) on your devices so they can find your Mac’s server.

REMEMBER: All of your sites are now easily accessible on the local network through xip.io mapping. So maybe you don’t want to run this when you’re in an untrusted local network (which you should never be in anyway).
You could also add HTTP authentication or other measures that you would use on a live site for access protection.

If you have any suggestions on how to make this tutorial better/easier/more secure, please comment!

Credits

I could not have written this tutorial without these great pieces:

http://mallinson.ca/osx-web-development/
http://blog.joefallon.net/2013/10/install-mysql-on-mac-osx-using-homebrew/
http://stackoverflow.com/questions/12570759/how-to-use-xip-io-with-several-virtualhosts-and-server-names-local-dev

Update 25 Oct 2015: I can confirm that this tutorial works for El Capitan, too—only two line numbers in php.ini differ from Yosemite. I have updated the text above accordingly.