Select Page

Want to do WordPress development on your local machine, or mirror your production environment locally?

This is a quick guide to getting Apache, SSL, MySQL, PHP and WordPress installed, configured and running locally on a Mac.

 

Apache

Apache is installed in /etc/apache2 and the main configuration file is in /etc/apache2/httpd.conf.

If you are unable to start Apache or get errors like “Cannot access directory ‘/private/var/log/apache2/” then make sure the directory /private/var/log/apache2 exists.

If it does not (i.e. you may have manually cleared the /private/var/log directory) simply recreate the apache2 directory (you’ll need to use sudo).

The permissions for the /private/var/log/apache2 directory should be:

You can see what version of Apache you have with:

httpd -v

The following Terminal commands allow you to control Apache:

Start Apache:

sudo apachectl start

Stop Apache:

sudo apachectl stop

Restart Apache:

sudo apachectl restart

Test Apache is working by navigating to http://localhost in your browser – you should see It works!:

However, if you get an error browsing to http://localhost then follow the instructions below in
Test Apache’s Configuration.


Test Apache’s Configuration

Check Apache’s configuration with:

apachectl configtest

You may get the following error:

AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1.
Set the 'ServerName' directive globally to suppress this message

If you do, edit /etc/apache2/httpd.conf, look for “ServerName” and set its value as follows:

ServerName localhost

Then restart Apache. If you got an error previously then you should now be able to browse to http://localhost.


Is Apache Running?

You can tell if Apache is running by running the following:

ps -ax | grep httpd

If there are one or more instances of the httpd process running then Apache is running.


Document Root

There are two document roots:  one at the system level, the other at the user level.

System
Alias: http://localhost/
Document Root: /Library/WebServer/Documents/

User
Normally you’d want to use this in preference to the system-level document root.

If it doesn’t already exist, create a directory named Sites in your home folder, then create a file named youraccountname.conf (I’m using my Mac account name “rarcher” in this example) in /etc/apache2/users/ as follows (it needs elevated permissions, so use sudo):

cd /etc/apache2/users/
sudo touch rarcher.conf

Edit the file and add the following (again, replace “rarcher” with your account name):

<Directory "/Users/rarcher/Sites/">
    AllowOverride All
    Options Indexes MultiViews FollowSymLinks
    Require all granted
</Directory>

Save the file. Permissions on the file should be as follows (if not, change with sudo chmod 644 rarcher.conf):

-rw-r--r--   1 root  wheel  131 18 Sep 17:58 rarcher.conf

SSL Configuration

In order to support SSL locally there are two possible approaches:

  1. Use self-signed newer (and slightly more complex to setup) SAN (Subject Alternative Name) style X509 certificates
  2. Use self-signed older (and simpler) CN (Common Name) style X509 certificates

Both approaches require us to:

  • Create a self-signed certificate
  • Add it to the system certificate store using the Mac Keychain Access utility
  • Configure Apache to allow SSL connections to localhost using our certificate

Note that since version 58, Chrome requires SSL certificates to use SAN-style certificates instead of the older, more common CN-style. See here for more details.

So, jump to the relevant section:

  1. Use SAN-style certificates with Chrome
  2. Use CN-style certificates with Safari

SAN-style certificates with Chrome

Open the main Apache config file /etc/apache2/httpd.conf and ensure the following modules are not commented out:

LoadModule authz_core_module libexec/apache2/mod_authz_core.so
LoadModule authz_host_module libexec/apache2/mod_authz_host.so
LoadModule userdir_module libexec/apache2/mod_userdir.so
LoadModule include_module libexec/apache2/mod_include.so
LoadModule rewrite_module libexec/apache2/mod_rewrite.so
LoadModule php7_module libexec/apache2/libphp7.so
LoadModule vhost_alias_module libexec/apache2/mod_vhost_alias.so
LoadModule socache_shmcb_module libexec/apache2/mod_socache_shmcb.so
LoadModule ssl_module libexec/apache2/mod_ssl.so
Include /private/etc/apache2/extra/httpd-userdir.conf
Include /private/etc/apache2/extra/httpd-vhosts.conf
Include /private/etc/apache2/extra/httpd-ssl.conf

Open /etc/apache2/extra/httpd-userdir.conf and uncomment:

Include /private/etc/apache2/users/*.conf

Note that for SSL support we’ll be using self-signed SAN (Subject Alternative Name) style X509 certificates.

For detailed instructions and a choice of either SAN or the older CN-style certificates, see Host SSL-Enabled WordPress sites on locahost.

Open /etc/apache2/extra/httpd-vhosts.conf and replace the entire contents with:

# HTTP Support
<VirtualHost *:80>
    ServerName localhost
    DocumentRoot "/Users/rarcher/Sites/"

    <Directory "/Users/rarcher/Sites/">
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
        Require all granted
    </Directory>
</VirtualHost>

# HTTPS Support
<VirtualHost *:443>
    ServerName localhost
    DocumentRoot "/Users/rarcher/Sites/"

    SSLEngine on
    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

    # SAN Certificates. Recommended when using Chrome
    SSLCertificateFile /etc/apache2/ssl/localhostcert.crt
    SSLCertificateKeyFile /etc/apache2/ssl/localhostcert.key

    # CN certificates. Recommended when using Safari
    #SSLCertificateFile /etc/apache2/ssl/localhost.crt
    #SSLCertificateKeyFile /etc/apache2/ssl/localhost.key

    <Directory "/Users/rarcher/Sites/">
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
        Require all granted
    </Directory>

    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +StdEnvVars
    </FilesMatch>

    <Directory "/Library/WebServer/CGI-Executables">
        SSLOptions +StdEnvVars
    </Directory>
</VirtualHost>

Open /etc/apache2/extra/httpd-ssl.conf, locate the default SSL virtual host and remove the entire configuration (we’re now configuring our SSL virtual host in httpd-vhosts.conf):

# Remove start from here...
<virtualhost _default_:443>
:
</virtualhost>
# ...end here

Create an SSL directory to hold our certificate and key:

sudo mkdir /etc/apache2/ssl

Generate a private key and X509 certificate for your SSL site (for example, you could use your Mac login password for the passphrase):

cd /etc/apache2/ssl
sudo openssl genrsa -des3 -out localhostca.key 2048

sudo openssl req -x509 -new -nodes -key localhostca.key -sha256 -days 1024 -out localhostca.pem

sudo openssl req -new -sha256 -nodes -out localhostcert.csr -newkey rsa:2048 -keyout localhostcert.key

Create a v3.ext data configuration file in the /etc/apache2/ssl directory so we can create a X509 v3 certificate (SAN-style certificate):

cd /etc/apache2/ssl
sudo touch v3.ext

Add the following to v3.ext:

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1=localhost

Create the .pem certificate:

sudo openssl x509 -req -in localhostcert.csr -CA localhostca.pem -CAkey localhostca.key -CAcreateserial -out localhostcert.crt -days 500 -sha256 -extfile v3.ext

Add the localhostca.pem certificate to your keychain:

sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain localhostca.pem

Open the Keychain Access app and locate the localhost certificate you just added:

Double-click the certificate to open it and make sure to set all trust settings to Always Trust:

Close Keychain Access, quit and restart Chrome and then restart Apache:

sudo apachectl restart

You should now be able to browse to both these URLs:

http://localhost/~rarcher
https://localhost/~rarcher

Should you encounter any errors you can check Apache’s configuration for syntax errors, typos, etc.:

apachectl configtest

Now jump to the section on PHP.


CN-style certificates with Safari

Open /etc/apache2/httpd.conf, look for the following two lines and make sure they are NOT commented-out:

LoadModule vhost_alias_module libexec/apache2/mod_vhost_alias.so
Include /private/etc/apache2/extra/httpd-vhosts.conf

This enables Virtual Hosts, which allows one Apache server to host multiple domains or interfaces (e.g. HTTP and HTTPS).

Now enable SSL by uncommenting the following entries:

LoadModule socache_shmcb_module libexec/apache2/mod_socache_shmcb.so
LoadModule ssl_module libexec/apache2/mod_ssl.so
Include /private/etc/apache2/extra/httpd-ssl.conf

Open /etc/apache2/extra/httpd-vhosts.conf and replace the entire contents of the file with the following (replacing rarcher with your username). The file should look like this when your edits are complete:

# HTTP Support
<VirtualHost *:80>
    ServerName localhost
    DocumentRoot "/Users/rarcher/Sites/"

    <Directory "/Users/rarcher/Sites/">
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
        Require all granted
    </Directory>
</VirtualHost>

# HTTPS Support
<VirtualHost *:443>
    ServerName localhost
    DocumentRoot "/Users/rarcher/Sites/"

    SSLEngine on
    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

    # SAN Certificates. Recommended when using Chrome
    #SSLCertificateFile /etc/apache2/ssl/localhostcert.crt
    #SSLCertificateKeyFile /etc/apache2/ssl/localhostcert.key

    # CN certificates. Recommended when using Safari
    SSLCertificateFile /etc/apache2/ssl/localhost.crt
    SSLCertificateKeyFile /etc/apache2/ssl/localhost.key

    <Directory "/Users/rarcher/Sites/">
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
        Require all granted
    </Directory>

    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +StdEnvVars
    </FilesMatch>

    <Directory "/Library/WebServer/CGI-Executables">
        SSLOptions +StdEnvVars
    </Directory>
</VirtualHost>

Open /etc/apache2/extra/httpd-ssl.conf, locate the default SSL virtual host and remove the entire configuration (we’re now configuring our SSL virtual host in httpd-vhosts.conf):

# Remove start from here...
<virtualhost _default_:443>
:
</virtualhost>
# ...end here

To support SSL we’re going to create a self-signed CN-style X509 certificate and key. Obviously, this is should only be used to support development projects.

Create an SSL directory to hold our certificate and key:

sudo mkdir /etc/apache2/ssl

Generate a private key and X509 certificate for your SSL site:

sudo openssl genrsa -out /etc/apache2/ssl/localhost.key 2048
sudo openssl req -new -x509 -key /etc/apache2/ssl/localhost.key -out /etc/apache2/ssl/localhost.crt -days 3650 -subj /CN=localhost

Add the certificate to your Mac’s System Keychain:

sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /etc/apache2/ssl/localhost.crt

If you open Keychain Access and search for localhost you should see our self-signed certificate:

Make sure the certificate has been added to the System keychain. If not, you can simply drag it into the System keychain:

Double-click the certificate to open it and then expand the certificate’s Trust section. Make sure each entry is set to Always Trust:

Close Keychain Access, quit and restart Safari and then restart Apache:

sudo apachectl restart

You should now be able to browse to both these URLs:

http://localhost/~rarcher
https://localhost/~rarcher

Should you encounter any errors you can check Apache’s configuration for syntax errors, typos, etc.:

apachectl configtest

PHP

macOS High Sierra comes with PHP version 7. We enabled it in Apache in the previous section by loading the required
module in /etc/apache2/httpd.conf:

LoadModule php7_module libexec/apache2/libphp7.so

To test the PHP installation:

Create a file named phpinfo.php in the root of your user-level document root directory (e.g. /Users/rarcher/Sites/).

Add the following code:

<?php phpinfo(); ?>

Save the file and then navigate to phpinfo.phphttps://localhost/~rarcher/phpinfo.php:

You can now search for the following important PHP variables that are related to various PHP operations.

If these variable are not set correctly you will encounter issues later on when using WordPress.

For example, upload_max_filesize:

Recommended PHP variable values are as follows:

memory_limit: 128M
upload_max_filesize: 64M
post_max_size: 64M
max_execution_time: 300
max_input_time: 300

If you need to adjust the values of the above variables two methods are outlined below.

Change PHP configuration in php.ini

You can see where your php.ini is located from the output of phpinfo.php:

Alternatively, run the following command:

php --ini

On my local system, by default the file is initially set to php.ini.default:

To override the default PHP values you need to create a named /private/etc/php.ini.

Make a copy of php.ini.default and rename it as php.ini (leave it in the same directory).

Make the permissions on the file read-only for all (chmod 444 php.ini).

Open php.ini and locate the values of each of the following variables and change them as suggested:

memory_limit: 128M
upload_max_filesize: 64M
post_max_size: 64M
max_execution_time: 300
max_input_time: 300

Save the file and restart Apache:

sudo apachectl restart

Browse again to https://localhost/~rarcher/phpinfo.php.

You should see that your new php.ini file has been read:

If you look for the variables we changed in php.ini you should see that they have indeed been changed.


MySQL

macOS High Sierra doesn’t come with MySQL so you need to download and install it from
https://dev.mysql.com/downloads/mysql/:

Note that at the time of writing (May 2018) the latest version of PHP (7.1.14) has an issue related the new authentication
scheme adopted by MySQL in version 8. You may therefore wish to use an earlier (pre version 8) version of MySQL until this is resolved.

MySQL will be installed in /usr/local/mysql and databases will be stored in /usr/local/mysql/data.

The first thing you should do after installing MySQL is add the following two paths to your /etc/paths file:

/usr/local/mysql/bin
/usr/local/mysql/support-files

Now we need to fix a socket error that can arise on Macs. By default the MySQL installation puts the socket file in
/tmp, but macOS looks for it in /var/mysql:

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

Change the root password. Close your Terminal window and open a new one (so it re-reads the /etc/paths file).

Stop MySQL, in case it’s running:

sudo mysql.server stop

Start MySQL in safe mode:

sudo mysqld_safe --skip-grant-tables

Leave the current Terminal window open and open a second window.

Log into MySQL as root:

mysql -u root

Enter the following MySQL commands (replace ‘newpassword’ with your new root password):

FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'newpassword';

Note syntax for changing the root password:

Quit by typying \q

Stop the safe mode instance of MySQL:

sudo mysql.server stop

Start MySQL:

sudo mysql.server start

Note that you can start MySQL either from the Terminal, as shown above, or via the Preferences applet:


phpMyAdmin

phpMyAdmin provides a simple, browser-based interface for managing your MySQL databases. You can also use apps like Sequel Pro (https://sequelpro.com).

Download phpMyAdmin, unzip and then move the folder with its contents into the user-level document root,
renaming the folder to phpMyAdmin.

Make the config folder:

mkdir ~/Sites/phpmyadmin/config

Set the permissions:

chmod o+w ~/Sites/phpmyadmin/config

Run the set up in the browser by browsing to https://localhost/~rarcher/phpmyadmin/setup/

Click New server:

Leave Basic settings at their default values.

In the Authentication tab, set the value of the MySQL password you setup earlier, then click Apply:

Now download the configuration – a file named config.inc.php will be saved to your Downloads folder:

Move config.inc.php to /Users/rarcher/Sites/phpmyadmin and delete the /Users/rarcher/Sites/phpmyadmin/config directory.

If you navigate to https://localhost/~rarcher/phpmyadmin you’ll now be able to manage your MySQL databases:


Possible phpMyAdmin Issues

I did once encounter an issue where I couldn’t login from the phpMyAdmin login page. No errors were displayed.

I used the following to solve the issue:

mysql -u root -p
flush hosts;
\q


Permissions

To run a website with no permission issues it is best to set the web root and its contents to be writeable by all,
since it’s a local development it shouldn’t be a security issue.

Let’s say that you have a site in the Sites folder (~/Sites/testsite) you would set it to be writeable like so:

sudo chmod -R 777 ~/Sites/testsite

Adding support for WordPress

Adding WordPress to a local site is very straightforward. Here, as an example, we’re going to create a WordPress-enabled
local site for “rarchersoftware”:

Download WordPress from https://wordpress.org.

Unzip and copy the contents of the archive to the root directory of your web site.

In this example we’ll be using /Users/rarcher/Sites/rarchersoftware:

We now need to create a database for WordPress to use.

Open https://localhost/~rarcher/phpmyadmin/ in your browser and login using your MySQL root account:

Click New to create a new database:

Give the database the same name as your web site and click Create:

Select the Privileges tab. Notice that root has full access to your database.

At this point you can opt to use the root account (a security risk, even on a local system) or create a new account,
which is what we’ll do here.

Click Add user account:

Add account details and click Go (bottom-right on window, not shown):

Make sure to set the Host name to Local (localhost).

Check Grant all privileges on database.

Make sure that the site’s directory is writable:

sudo chmod -R 777 ~/Sites/rarchersoftware

Open https://localhost/~rarcher/rarchersoftware/index.php in your browser – this will redirect to the following page:

Click Let’s go!

Fill in the following details:

Submit the details.

If no error is reported:

  • Your wp-config.php file will have been created and you’ll see the following
  • Click Run the installation:

If you do get an error:

  • The directory probably isn’t writable by the script
  • Copy the provided configuration code and paste it into an editor
  • Save it as wp-config.php in your site’s root folder (along with all the other WordPress files)
  • Click Run the install. You can then fill in details for a WordPress admin user for your site.

Click Install WordPress:

You should then see a success confirmation page.

Click the Log In button and supply the account details for the WordPress user you just created:

Finally, after logging in you will see your site’s WordPress dashboard:


Potential Errors

General Checks

Open your site’s wp-config.php file (which is in the site’s root) and make a note of the database name, database user and database user password. Then check the following:

Make sure the database name listed as DB_NAME in wp-config.php is the same database name shown in phpMyAdmin:

  • If not, drop the database in myPhpAdmin and recreate it using the name listed in wp-config.php
  • That way, if you export the site back to your remote host you won’t break anything

Make sure the database user listed as DB_USER in wp-config.php actually exists under the Privileges tab in phpMyAdmin:

  • If not, add a user account (see the Privileges tab for your database) using the name and password specified in wp-config.php
  • Make sure the host name is configured to be Local (localhost), rather than the default % wildcard

Make sure that DB_HOST in wp-config.php is set to ‘localhost’:

Database Error: Error establishing a database connection

If you can’t connect to the database, make sure the Host name for the database user account (see DB_NAME in wp-config.php) is set to localhost instead of the default % (any host) – see above General Checks.

403: You don’t have permission to access index.php on this server

This can happen when the site is not readable. Use the following:

sudo chmod -R 755 ~/Sites/sitename

403: You don’t have permission to access wp-login.php on this server

If you get a 403 Forbidden error while trying to access your site’s wp-admin dashboard, try logging in first by going to:

https://localhost/~yourname/yoursite/wp-login.php

After logging in you should then be allowed access to the admin dashboard.

404 – Not Found (index.php)

If you can browse OK to the admin dashboard and default home page but not to other pages.

Goto your site’s dashboard and then select Settings > Permalinks.

Look at the bottom of the page. You may see suggested changes to your .htaccess file.

Open your site’s .htaccess file and look for an existing #BEGIN WordPress … #END WordPress block.

Replace the existing configuration with that suggested.

Restart Apache and try again.

If you revisit then Permalinks settings page you see no suggested changes to .htaccess – this means the configuration is good.

Plugin Issues

If you’re still getting errors, try deactivating plugin one-by-one until the issue goes away.

Configuration changes

If all the above suggestions have failed to resolve the issue, try editing the following values in wp-config.php:

DB_HOST – make sure this is set to ‘localhost’.

WP_SITEURL – where your WordPress core files reside on the local machine.

WP_HOME – the address you want people to type in their browser to reach your WordPress site locally.

FORCE_SSL_ADMIN – review this setting. Look for FORCE_SSL_ADMIN and set it to false only if SSL was NOT enabled on the remote machine.