macOS Local Development Setup

A couple weeks ago I decided to replace MAMP on my MacBook with free tools for local PHP development. I didn’t find a guide online that was perfect for what I wanted, so here are the steps I used, pieced together from several other guides.


  • This guide was written for macOS 10.14 Mojave. Other versions of macOS may require changes to some of the steps.
  • I use Homebrew to install MySQL and phpMyAdmin.
  • You will need a way to edit files from the command line. I use Atom, which can be used to edit file by running the atom [filename] command.


macOS Mojave comes with Apache 2.4.34 pre-installed. This isn’t the latest version, but it was good enough for me. If you want to install a newer version, I suggest following the guide on

Apache Configuration

Edit the Apache httpd.conf file, found here: /etc/apache2/httpd.conf.

We need to enable things like Apache rewriting, includes, user directories, virtual hosts, and PHP. To do so, make sure the following lines are uncommented:

LoadModule authz_core_module libexec/apache2/
LoadModule authz_host_module libexec/apache2/
LoadModule userdir_module libexec/apache2/
LoadModule rewrite_module libexec/apache2/
LoadModule include_module libexec/apache2/
LoadModule php7_module libexec/apache2/
Include /private/etc/apache2/extra/httpd-vhosts.conf
Include /private/etc/apache2/extra/httpd-userdir.conf

To have Apache look for PHP indexes, add index.php to the DirectoryIndex. It should look like this:

<IfModule dir_module>
    DirectoryIndex index.html index.php

Find the ServerName setting and set it to localhost:

ServerName localhost

Make sure to save and close the file, then restart Apache:

sudo apachectl restart

Here are other commands you might want to know if you need to start or stop Apache:

sudo apachectl start
sudo apachectl stop

Run the Apache configuration test to make sure there are no errors:

apachectl configtest

Apache User Configuration

Open the user home directories configuration file: /etc/apache2/extra/httpd-userdir.conf.

Uncomment the following line to have Apache load configuration files in the users:

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

Save and close the file.

Now we need to check to see if a configuration file exists for your user. Run the following command:

ls /etc/apache2/users/*.conf

If a conf file for the current macOS user is not listed, create one:

sudo touch username.conf

Open the username.conf file. To allow the user the proper permissions, add the following to the file:

<Directory "/Users/username/Websites/Path/">
    Options Indexes MultiViews FollowSymLinks
    Require all granted
    AllowOverride All
    Order allow,deny
    Allow from all

Be sure to change the Directory path to the location where you will store your local websites. Save and close the file.

Restart Apache:

sudo apachectl restart


Every time you want to set up a new local project, you will need to add a host to the macOS hosts file and add a virtual host to the Apache httpd-vhosts.conf file. (Note: You can buy a nice app called VirtualHostX to help with this if you don’t want to mess with the command line each time.)

macOS Host

To add a host to macOS, open /etc/hosts, and add the local domain to the file:

A lot of people like to use something like or domain.local, but I like to use something like This way is nice to me because I use 1Password to handle all my passwords, and it will recognize the local domain for stored passwords on the production site.

After making your changes, save and close the file.

Apache Virtual Host

You will now need to add a virtual host to Apache to match the host added to macOS. Open /private/etc/apache2/extra/httpd-vhosts.conf. Add the new VirtualHost to the file:

<VirtualHost *:80>
    DocumentRoot "/Users/Websites/Path/"

Optionally, you can add virtual host rewriting to load remote images for images missing in the local environment, a trick I used often in MAMP. Here is an example for Drupal uploads:

<VirtualHost *:80>
    DocumentRoot "/Users/Websites/Path/"
    RewriteEngine on
    RewriteCond %{REQUEST_URI} ^/sites/default/files/(.*)$
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^/sites/default/files/(.*)$$1 [L]

Restart Apache:

sudo apachectl restart


macOS Mojave comes with PHP 7.1 pre-installed. Again, this was good enough for me, but if you want to install a newer version (or multiple versions), try following the guide.

PHP Configuration

Create a php.ini file by copying the default configuration file:

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

Set the proper permissions for the php.ini file:

sudo chmod 644 /etc/php.ini

Open the /etc/php.ini file. Find the error_reporting and display_errors settings and turn them on:

error_reporting = E_ALL | E_STRICT
display_errors = On

Find the date.timezone setting and set the timezone:

date.timezone = America/Chicago

Increase file upload and memory limits to fit your needs:

upload_max_filesize = 128M
post_max_size = 128M
max_execution_time = 300
max_input_time = 300
memory_limit = 128M

Save and close the file.


Install MySQL with Homebrew:

brew install mysql

Start MySQL and set it to start at login:

brew services start mysql

Run the MySQL configuration:


The configuration will now ask a series of questions. I went with the following options:

  • Validate password component: Yes
  • Choose the password validation policy level and set a root password
  • Remove anonymous users: Yes
  • Disallow root login remotely: Yes
  • Remove test database and access to it: Yes
  • Reload privilege tables now: Yes

MySQL on macOS will get a 2002 MySQL socket error that will need to be fixed by running the following commands:

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


If you would like to manage your MySQL databases with phpMyAdmin, install phpMyAdmin with Homebrew:

brew install phpmyadmin

Open the Apache configuration file (/etc/apache2/httpd.conf) and add the following to enable access to phpMyAdmin:

Alias /phpmyadmin /usr/local/share/phpmyadmin
<Directory /usr/local/share/phpmyadmin/>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    <IfModule mod_authz_core.c>
        Require all granted
    <IfModule !mod_authz_core.c>
        Order allow,deny
        Allow from all

Save and close the file and then restart Apache:

sudo apachectl restart

Open the phpMyAdmin configuration file (/usr/local/etc/ and change localhost to (this prevents an error I was getting):

$cfg['Servers'][$i]['host'] = '';

Add a secret passphrase:

$cfg['blowfish_secret'] = 'My secret passphrase';

Add a TempDir in the directories section of the config file:

$cfg['UploadDir'] = '';
$cfg['SaveDir'] = '';
$cfg['TempDir'] = '/tmp';

Save and close the file.

You can now access phpMyAdmin with user root and the password you set during the MySQL configuration:


Authentication Method Error

At this point, I was getting following error when trying to access phpMyAdmin:

mysqli_real_connect(): (HY000/2054): The server requested authentication method unknown to the client

To fix this error, open MySQL:

mysql -u root -p

Run the following command:

ALTER USER 'username'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

Exit MySQL by running the exit command.

Command Aliases

I set up a few aliases in my .bash_profile as shortcuts for managing my local server:

# Apache
alias start-apache='sudo apachectl start'
alias stop-apache='sudo apachectl stop'
alias restart-apache='sudo apachectl restart'

# Config files
alias config-apache="sudo atom /etc/apache2/httpd.conf"
alias config-apache-users="sudo atom /etc/apache2/users/"
alias config-hosts="sudo atom /etc/hosts"
alias config-vhosts="sudo atom /private/etc/apache2/extra/httpd-vhosts.conf"
alias config-php="sudo atom /etc/php.ini"


An Event Apart: “The New Design Material”

Josh Clark speaking at An Event Apart Orlando 2018 on October 10, 2018

Just as mobile defined the last decade of digital products, machine learning is set to define the next. Learn to use machine-generated content, insight, and interaction as design material in your everyday work. Refit familiar design and UX process to work with the grain of the algorithm, to help the machines solve real problems without creating new ones. This lively and inspiring talk explores the technologies and practical techniques that you can use today—like right now—not only to make existing products better but to imagine surprising new services. The challenges and opportunities of machine learning are plenty; learn to handle this powerful new design material with care and respect.

Continue reading An Event Apart: “The New Design Material”

An Event Apart: “Leveling Up Your Design Communication”

Aarron Walter speaking at An Event Apart Orlando 2018 on October 10, 2018

Design is a medium for communication, and to do it well, we must cultivate our own communication skills. Within design teams, we do our best work when we create a culture of feedback shaped by our creative space and our design review process. Beyond the design tribe, our work thrives when it’s communicated in language that aligns to the goals of the business and invites participation early and often. In this presentation, Aarron will share the experiences of real design teams at Apple, Spotify, and other organizations to show how to improve the communication of design both inside your team and with key outside stakeholders. You’ll see how to run effective design reviews and retrospectives which will help you create a culture of feedback that produces better work, helps designers sharpen their skills, and communicates the value of design by making it more transparent and inviting.

Continue reading An Event Apart: “Leveling Up Your Design Communication”

An Event Apart: “Name That Script!”

Trent Walton speaking at An Event Apart Orlando 2018 on October 10, 2018

How many third-party scripts are loading on our web pages these days? How can we objectively measure the value of these (advertising, a/b testing, analytics, etc.) scripts—considering their impact on web performance, user experience, and business goals? We’ve learned to scrutinize content hierarchy, browser support, and page speed as part of the design and development process. Similarly, Trent will share recent experiences and explore ways to evaluate and discuss the inclusion of 3rd-party scripts.

Continue reading An Event Apart: “Name That Script!”

An Event Apart: “’Til Launch Do Us Part”

Dan Mall speaking at An Event Apart Orlando 2018 on October 9, 2018

From one designer to a front-end developer: I’m so grateful for you. You take my pretty pictures and turn them into real-live websites and applications; you convert ideas and sketches into real things that people can use. And even despite that superpower, you rarely get the respect you deserve. It’s time for that to change. No longer will I throw my comps over the proverbial wall for you to blindly build. I’ll change my process for you. Let’s sketch together more to be more efficient and effective as a team. Let’s decide in the browser more. I’ll learn to write JSON for you. Let’s share stories about new, more modern ways of shipping products at higher quality in record time. This is gonna be great!

Continue reading An Event Apart: “’Til Launch Do Us Part”

An Event Apart: “Durable Design”

Jon Tan speaking at An Event Apart Orlando 2018 on October 9, 2018

We’ve come such a long way in the last 20 years from a grass-roots web standards movement to Wired magazine launching a standards-based interface in 2003, to today, with all the tools and methods that inform current web design. But, where next? This talk makes a radical argument for recidivism in our design thinking; a return to durable, aesthetic, and inclusive web design. Through evidence and examples, you’ll learn to design for serendipity, for speed, and for economy of time, resources, and attention. Durable design is responsive design for the next decade, and it starts now.

Continue reading An Event Apart: “Durable Design”

An Event Apart: “Building More Expressive Products”

Val Head speaking at An Event Apart Orlando 2018 on October 9, 2018

The products we design today must connect with customers across different screen sizes, contexts, and even voice or chat interfaces. As such, we create emotional expressiveness in our products not only through visual design and language choices, but also through design details such as how interface elements move, or the way they sound. By using every tool at our disposal, including audio and animation, we can create more expressive products that feel cohesive across all of today’s diverse media and social contexts. In this session, Val will show how to harness the design details from different media to build overarching themes—themes that persist across all screen sizes and user and interface contexts, creating a bigger emotional impact and connection with your audience.

Continue reading An Event Apart: “Building More Expressive Products”

An Event Apart: “Maintaining Design Systems”

Brad Frost speaking at An Event Apart Orlando 2018 on October 9, 2018

By now, ’most every in-house team has some form of design system initiative underway. Yet many designers and developers on those teams still struggle to make the system really take root in their organization. Working together, designers and developers create wonderful, reusable components, tools, guidelines, and documentation. But if those elements don’t reflect the reality of how the organization builds its products, all their effort is for naught. Having spent years creating, evangelizing, and teaching design systems and corporate integration of same, Brad Frost is here to share strategies and methods to ensure your design system stands the test of time. You’ll learn how to keep your system and the products it serves in sync, and you’ll understand how to maintain and evolve your design system to give your users get the best possible experience.

Continue reading An Event Apart: “Maintaining Design Systems”

An Event Apart: “Why Design Systems Fail”

Una Kravets speaking at An Event Apart Orlando 2018 on October 9, 2018

Design systems are hot right now, and for good reason. They promote a modular approach to building a product, promote organizational unity, and ensure stability via reusable code snippets and utility styles. They make prototyping a breeze, and provide a common language for both designers and developers. But sometimes design systems are underutilized within organizations. Why is that, when they’re so darn useful? In an engaging hour, Una will draw on years of experience to explore what makes design systems successful, analyze real examples of success and failure, and show how to make sure your design system has the building blocks it needs to grow into a successful product.

Continue reading An Event Apart: “Why Design Systems Fail”

An Event Apart: “Designing an Intuitive Navigation”

Gerry McGovern speaking at An Event Apart Seattle 2018 on April 4, 2018.

Confusing menus and links are the number one issue people have in getting stuff done in digital. Sure, search is critical but even the best search usually only jumps you down a few levels in the navigation hierarchy. To complete your task you nearly always have to click more, and selecting the right link is where so many people get frustrated, confused and annoyed. Learn about methods to reduce confusion and increase speed and simplicity for your customers. Learn how to use evidence to uncover the core navigational mental models within people’s minds and to create intuitive interfaces based on these mental models. Learn how to apply essential navigational principles such as: Familiarity, Unity, Essentiality, and Forward-Focus.

Continue reading An Event Apart: “Designing an Intuitive Navigation”