Mike Morearty
03 Feb 2013

The hacker’s way to install Apache, PHP, MySQL, and/or WordPress on OS X Mountain Lion

By “the hacker’s way,” I mean that these instructions are for people who:

  1. prefer using the command line; and
  2. want to understand what’s going on, so they can undo or fix things later if necessary.

You can follow the below instructions without installing all four software packages. For example, you can install Apache+PHP+MySQL without installing WordPress, and so on.

Wherever I mention “vim” below, if you aren’t familiar with vim, you can obviously substitute any other editor you want. “nano” is probably the easiest one.

To install Apache

Apache is already installed in Mountain Lion; it just needs to be enabled. Do this:

sudo vim /etc/apache2/users/`whoami`.conf

Put this in that file (change USERNAME):

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

Create the ~/Sites directory, which will be Apache’s root directory for http://localhost/~USERNAME:

mkdir ~/Sites

If you want Apache to launch automatically after every reboot:

sudo launchctl load -w /System/Library/LaunchDaemons/org.apache.httpd.plist

# To prevent it from auto-loading after future reboots:
sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist

# To stop or restart it for now, without changing future reboot behavior:
sudo launchctl unload -F /System/Library/LaunchDaemons/org.apache.httpd.plist
sudo launchctl load -F /System/Library/LaunchDaemons/org.apache.httpd.plist

If you only want to start Apache now, and require manual launch after every reboot:

sudo apachectl start

# If you need to restart or stop it later:
sudo apachectl restart
sudo apachectl stop

Try it out:

echo 'This is ~/Sites/index.html' > ~/Sites/index.html
open http://localhost/~`whoami`

If you need to make any configuration changes to Apache, the config file is /etc/apache2/httpd.conf.

To install php

PHP is already installed; it just needs to be enabled. Do this:

sudo vim /etc/apache2/httpd.conf

Find the line that says this:

#LoadModule php5_module libexec/apache2/libphp5.so

Remove the leading # comment character and then save the file.

By default, php code does not support the shorter <? ... ?> tags, but instead requires the more verbose <?php ... ?> tags. If you want to enable the shorter tags:

sudo vim /private/etc/php.ini

And change short_open_tag = Off to short_open_tag = On.

Then restart Apache, as described above:

# if you installed Apache to launch automatically on reboot:
sudo launchctl unload -F /System/Library/LaunchDaemons/org.apache.httpd.plist
sudo launchctl load -F /System/Library/LaunchDaemons/org.apache.httpd.plist

# otherwise:
sudo apachectl restart

Test it out:

echo '<?php phpinfo() ?>' > ~/Sites/phptest.php
open "http://localhost/~`whoami`/phptest.php"

If you need to modify PHP’s configuration, its main config file is /private/etc/php.ini. (The output of the phpinfo() call in the above phptest.php file also tells you that.)

To install MySQL

If you don’t already have Homebrew, install it. Then:

brew install mysql

As per the instructions that were displayed by brew install mysql, set up databases to run as your user account with:

unset TMPDIR
mysql_install_db --verbose --user=`whoami` --basedir="$(brew --prefix mysql)" \
    --datadir=/usr/local/var/mysql --tmpdir=/tmp

Make a symlink to the MySQL socket so that PHP can find it where it expects to:

sudo mkdir -p /var/mysql
sudo ln -s /tmp/mysql.sock /var/mysql/mysql.sock

Relaunch MySQL:

launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist

MySQL’s user name is root; there is initially no password. Set a password, so no one can hack in:

sudo /usr/local/opt/mysql/bin/mysqladmin -u root password 'YOUR_MYSQL_PASSWORD'

Try it out. Create a test database:

$ mysql -uroot -p
[enter password when prompted]
mysql> create database mytestdb;
mysql> quit

Then put the following in ~/Sites/mysql.php:

<?php
$mysqli = new mysqli('localhost', 'root', 'YOUR_MYSQL_PASSWORD', 'mytestdb');
if ($mysqli->connect_error) {
    die('Connect Error (' . $mysqli->connect_errno . ') '
        . $mysqli->connect_error);
}
echo 'Success... ' . $mysqli->host_info . "\n";
$mysqli->close();
?>

Then:

open "http://localhost/~`whoami`/mysql.php"

After it works, delete the test database:

$ mysql -uroot -p
[enter password when prompted]
mysql> drop database mytestdb;
mysql> quit

To install WordPress

Download WordPress. Suppose you have downloaded it as, for example, ~/Downloads/wordpress-3.5.1.zip.

Unzip it into a wordpress subdirectory of your Sites directory:

cd ~/Sites
unzip ~/Downloads/wordpress-3.5.1.zip

Make sure WordPress is able to write to the wp-content directory (so, for example, WordPress can upload JPG files and so on). Apache runs as user _www in group _www, so we’ll change the wp-content directory’s group to _www, and make sure it is group-writable:

sudo chgrp -R _www wordpress/wp-content

Try it out:

open "http://localhost/~`whoami`/wordpress"

You will be asked to enter the following information. Enter is as shown below (the only values you will need to change from the defaults are “User Name” and “Password”):

Database name: wordpress
User Name:     root
Password:      (leave blank)
Database Host: localhost
Table Prefix:  wp_

Click Submit. Oops, an error message. You need to manually create the wordpress database.

From the command line:

$ mysql -uroot
mysql> create database wordpress;
mysql> quit

Now go back to the web page, and try again. But it should now display a different error message:

Sorry, but I can’t write the wp-config.php file. You can create the wp-config.php manually and paste the following text into it.

Okay. So do that. Copy the text, and paste it into ~/Sites/wordpress/wp-config.php. Then return to the web page and try one more time; it should succeed. (Note: We could have changed your filesystem’s permissions to give WordPress permission to write to wp-config.php, but I prefer not to do that, for security reasons.)

You’re done! If you have any corrections, please let me know.

comments powered by Disqus