Some time ago I was doing some hacking for Chamilo LMS (a Free Software E-Learning system) which uses a classic web environment consisting of Apache + PHP + MySQL. Setting this up in GNU/Linux is trivial, but a MacBook with OSX (now macOS) is a different story.
After some trial and error, I settled on a pure Homebrew installation and decided to write this blog post to help others in a similar situation.
My first google searches led me to MAMP, an OSX bundle with Apache + MySQL + PHP. However MAMP had many weird quirks that forced me to maintain a local set of patches just to get things working predictably.
The other popular alternative for a web environment consisted of mixing OSX’s included Apache with software patched in from Homebrew. That meant modifying files in
/etc, and mixing software from two completely different sources.
Overall it sounded like a very bad idea because you can’t just
apt-get install --reinstall if you break something in OSX.
In summary, these are the reasons why I preferred a pure Homebrew installation:
- No need for root. Everything is user–writable in
- Vanilla versions for everything, and easy to keep the individual components up–to–date with upstream, or mix different versions if you want.
- Easy to destroy and replicate with a guide like this, in case you break something.
- Usable, non–root, PEAR system for installing PHP stuff.
- The popular “patched-in” setups make you brew almost all this anyway, so better go the extra mile and have a more reliable system.
I couldn’t find a simple and clean tutorial that didn’t reinvent the wheel so here’s my own tutorial to get Apache + MySQL + PHP running on OSX, using only Homebrew.
By the way: For this guide I assume you know your way around a terminal, at least enough to use something like Homebrew.
#1- Install Homebrew
First of all you need to install Homebrew. Head over to Homebrew’s homepage for instructions.
Before brewing any software it’s a good idea to run a health check, and a quick update & upgrade just to make sure we are not missing anything new:
$ brew doctor
$ brew update && brew upgrade
Pay attention to whatever that says and follow any instructions. In case something seems wrong you can check Homebrew’s installation instructions for troubleshooting.
Also, you need to add this to your
.bash_profile, to make sure you use Homebrew’s installed binaries instead of your system’s pre installed ones (specially important for PHP-FPM).
# Include Homebrew's sbin path
#2- Install Apache (httpd24) and PHP
We’ll begin by installing (brewing) Apache 2.4 and PHP 7.0:
$ brew install homebrew/apache/httpd24
$ brew install homebrew/php/php70
This will take a few minutes, you’ll see a summary of each operation after each command finishes.
Remember that if you face any issues along this process you can consult the
brew info command for any package and get some extra tips and information. For example PHP’s info has some useful tips for PEAR users (we won’t cover PEAR in this guide):
$ brew info php70
After Apache and PHP are done, we can add phpmyadmin into the mix:
$ brew install phpmyadmin
phpmyadmin is a web app that helps you administer your MySQL installation, it’s a must have if you’ll be working with MySQL.
#3- Configuring Apache 2.4 to use PHP-FPM, and a user controlled DocumentRoot
We’ll configure a VirtualHost in Apache that uses PHP, and also sets a user controlled DocumentRoot instead of the traditional location inside
I prefer to keep things in my user directory and outside
/usr/local/ so I can quickly browse my code and files in Finder if I have to.
To get this set let’s go and edit
Replace the existing VirtualHost configuration for the following. Make sure to edit things as you see fit. At the very least make sure the paths exist:
<VirtualHost *:8080> <FilesMatch \.php$> # 2.4.10+ can proxy to unix socket # SetHandler "proxy:unix:/var/run/php5-fpm.sock|fcgi://localhost/" # Else we can just use a tcp socket: SetHandler "proxy:fcgi://127.0.0.1:9000" </FilesMatch> <IfModule dir_module> DirectoryIndex index.html index.php </IfModule> ServerAdmin firstname.lastname@example.org DocumentRoot "/Users/YOUR-USER-NAME/Sites" ServerName localhost ServerAlias localhost ErrorLog "/Users/YOUR-USER-NAME/Sites/logs/localhost-error_log" CustomLog "/Users/YOUR-USER-NAME/Sites/logs/localhost-access_log" common <Directory /Users/YOUR-USER-NAME/Sites> Options Indexes FollowSymLinks MultiViews AllowOverride All Require all granted </Directory> # PHPMyAdmin Alias /phpmyadmin /usr/local/share/phpmyadmin <Directory /usr/local/share/phpmyadmin/> Options Indexes FollowSymLinks MultiViews AllowOverride All Require all granted </Directory> </VirtualHost>
Now let’s make sure the main Apache configuration is using our new VirtualHost configuration, and that the proper modules are loaded.
/usr/local/etc/apache2/httpd.conf and make sure the following lines are not commented (they are already present but commented with a ‘#’ symbol):
LoadModule proxy_module libexec/mod_proxy.so LoadModule proxy_fcgi_module libexec/mod_proxy_fcgi.so LoadModule rewrite_module libexec/mod_rewrite.so Include /usr/local/etc/apache2/2.4/extra/httpd-vhosts.conf
For extra credit let’s edit PHP’s configuration to have a default time zone. This helps when you are debugging code that doesn’t set a timezone explicitly. It makes PHP print timestamps in your local time.
/usr/local/etc/php/7.0/php.ini and make sure to edit the
date.timezone line, like this:
date.timezone = America/Lima (or whatever works for you)
#4- Setting up MySQL
The last piece we need is MySQL:
$ brew install mysql
After that installs we’ll secure the server a little bit by running:
$ brew services start mysql
By the way,
brew services controls services installed through Homebrew. You can see what’s available and its status running:
$ brew services list
Now let’s see if everything is working.
You can create an
index.php file with a call to
phpinfo(); inside your configured root (probably
/Users/YOUR-USER-NAME/Sites) to test if PHP is working fine and what modules are being loaded into it.
Let’s start the Apache and PHP services:
$ brew services start httpd24
$ brew services start php70
(Note that for whatever reason
brew services does not print out an error if Apache fails to start. If at this point there’s any problem it’s probably with the Apache configuration, so a syntax check with
apachectl -S might help you.)
This looks like a lot of work, but it’s fairly quick with this cheat sheet, in the long run it’s much safer and easier to maintain and adapt thanks to brew’s excellent tools. A quick
brew update && upgrade will take care of updating you to the latest versions of everything.
Last updated on 2016-12-22: Apache 2.4.23, PHP 7.0.14, MySQL 5.7.16 and OSX 10.12.2.